From 78cbeb0dc0b754d24afd61c32341d0a2088b8648 Mon Sep 17 00:00:00 2001 From: Vivek Mishra Date: Fri, 2 Aug 2013 11:25:06 +0530 Subject: [PATCH 1/7] New code structure --- src/README.md | 190 ++ src/kundera-cassandra/pom.xml | 201 ++ .../client/cassandra/CassandraClientBase.java | 1998 ++++++++++++++++ .../cassandra/CassandraClientProperties.java | 86 + .../cassandra/common/CassandraConstants.java | 95 + .../cassandra/common/CassandraUtilities.java | 202 ++ .../config/CassandraPropertyReader.java | 290 +++ .../datahandler/CassandraDataHandler.java | 121 + .../datahandler/CassandraDataHandlerBase.java | 1859 +++++++++++++++ .../cassandra/datahandler/DataHandler.java | 26 + .../datahandler/DataHandlerBase.java | 26 + .../cassandra/index/CassandraIndexHelper.java | 79 + .../cassandra/index/InvertedIndexHandler.java | 70 + .../index/InvertedIndexHandlerBase.java | 316 +++ .../client/cassandra/pelops/PelopsClient.java | 873 +++++++ .../cassandra/pelops/PelopsClientFactory.java | 484 ++++ .../cassandra/pelops/PelopsDataHandler.java | 92 + .../pelops/PelopsInvertedIndexHandler.java | 215 ++ .../client/cassandra/pelops/PelopsUtils.java | 210 ++ .../client/cassandra/query/CassQuery.java | 770 +++++++ .../query/CassandraEntityReader.java | 326 +++ .../cassandra/query/ResultIterator.java | 541 +++++ .../schemamanager/CassandraSchemaManager.java | 2019 +++++++++++++++++ .../CassandraValidationClassMapper.java | 192 ++ .../cassandra/service/CassandraHost.java | 343 +++ .../service/CassandraHostConfiguration.java | 289 +++ .../service/CassandraRetryService.java | 149 ++ .../cassandra/thrift/CQLTranslator.java | 710 ++++++ .../client/cassandra/thrift/ThriftClient.java | 1058 +++++++++ .../cassandra/thrift/ThriftClientFactory.java | 387 ++++ .../cassandra/thrift/ThriftDataHandler.java | 124 + .../thrift/ThriftDataResultHelper.java | 210 ++ .../thrift/ThriftInvertedIndexHandler.java | 337 +++ .../client/cassandra/thrift/ThriftRow.java | 246 ++ .../thrift/TranslationException.java | 68 + .../main/resources/log4j-server.properties | 29 + .../src/main/resources/solandra.properties | 46 + .../config/CassandraDefaultSuperUser.java | 92 + .../config/CassandraDefaultUser.java | 80 + ...CassandraSchemaGenerationUsingXmlTest.java | 158 ++ .../cassandra/config/CassandraSuperUser.java | 92 + .../cassandra/config/CassandraUser.java | 80 + .../cassandra/config/CassandraUserTest.java | 92 + .../cassandra/thrift/AddressHandler.java | 20 + .../cassandra/thrift/AddressListenerDTO.java | 40 + .../cassandra/thrift/CompositeTypeRunner.java | 184 ++ .../cassandra/thrift/PersonHandler.java | 35 + .../cassandra/thrift/PersonIdentity.java | 69 + .../cassandra/thrift/PersonIdentityTest.java | 108 + .../thrift/PersonnelListenerDTO.java | 154 ++ .../thrift/PersonnelListenerDTOTest.java | 79 + .../client/cassandra/thrift/Phone.java | 38 + .../client/cassandra/thrift/PhoneId.java | 36 + .../cassandra/thrift/ThriftClientTest.java | 200 ++ .../client/cassandra/thrift/cql/CQLUser.java | 81 + .../cassandra/thrift/cql/CQLUserTest.java | 95 + .../cql/CassandraBatchProcessorCQLTest.java | 49 + .../thrift/cql/CountersTestOnCql.java | 26 + .../thrift/cql/LoggingConfiguration.java | 83 + .../thrift/cql/LoggingConfigurationTest.java | 148 ++ .../cassandra/thrift/cql/OTMCRUDCQLTest.java | 40 + .../thrift/cql/PersonCassandraCQLTest.java | 31 + .../thrift/cql/StudentCassandraCQLTest.java | 31 + .../thrift/cql/SuperCountersTestOnCql.java | 26 + .../thrift/entities/AddressMToM.java | 54 + .../cassandra/thrift/entities/PersonMToM.java | 75 + .../com/impetus/client/crud/BaseTest.java | 312 +++ .../crud/CassandraAuthenticationTest.java | 278 +++ .../client/crud/CassandraIdQueryTest.java | 619 +++++ .../com/impetus/client/crud/Employee.java | 126 + .../client/crud/EntityTransactionTest.java | 405 ++++ .../java/com/impetus/client/crud/Group.java | 82 + .../client/crud/MTOBiSelfAssociationTest.java | 128 ++ .../java/com/impetus/client/crud/Month.java | 6 + .../com/impetus/client/crud/MyTestEntity.java | 107 + .../com/impetus/client/crud/OTMCRUDTest.java | 111 + .../client/crud/PersonAssociationTest.java | 234 ++ .../com/impetus/client/crud/PersonAuth.java | 127 ++ .../impetus/client/crud/PersonCassandra.java | 179 ++ .../crud/PersonCassandraLuceneTest.java | 618 +++++ .../client/crud/PersonCassandraTTLTest.java | 514 +++++ .../client/crud/PersonCassandraTest.java | 626 +++++ .../client/crud/PersonLuceneCassandra.java | 168 ++ .../java/com/impetus/client/crud/Token.java | 62 + .../com/impetus/client/crud/TokenClient.java | 57 + .../impetus/client/crud/TransientUser.java | 86 + .../client/crud/TransientUserTest.java | 158 ++ .../crud/UpdateDeleteJPQLLiteralTest.java | 232 ++ .../client/crud/UserPromoCodeTest.java | 199 ++ .../client/crud/batch/AddressBatch.java | 78 + .../CassandraBatchProcessorMixedTest.java | 249 ++ .../batch/CassandraBatchProcessorTest.java | 246 ++ .../client/crud/batch/PersonBatch.java | 128 ++ .../batch/PersonBatchCassandraEntity.java | 127 ++ .../client/crud/collection/BlogPost.java | 173 ++ .../client/crud/collection/BlogPostTest.java | 519 +++++ .../crud/compositeType/CQLTranslatorTest.java | 105 + .../CassandraCompositeTypeTest.java | 546 +++++ .../compositeType/CassandraCompoundKey.java | 89 + .../CassandraEmbeddedAssociation.java | 116 + .../compositeType/CassandraPrimeUser.java | 129 ++ .../compositeType/CompositeDataTypeTest.java | 513 +++++ .../compositeType/CompoundKeyDataType.java | 481 ++++ .../crud/compositeType/PrimeUserDataType.java | 109 + .../association/AddressOTOPK.java | 82 + .../association/CassandraAddressUniOTM.java | 40 + .../association/CassandraUserOTMTest.java | 203 ++ .../association/CassandraUserUniOTM.java | 60 + .../compositeType/association/UserInfo.java | 131 ++ .../association/UserInfoTest.java | 216 ++ .../compositeType/association/UserOTOPK.java | 72 + .../association/UserOTOPKTest.java | 198 ++ .../client/crud/countercolumns/Counters.java | 80 + .../crud/countercolumns/CountersTest.java | 426 ++++ .../crud/countercolumns/SubCounter.java | 44 + .../crud/countercolumns/SuperCounters.java | 108 + .../countercolumns/SuperCountersTest.java | 480 ++++ .../client/crud/datatypes/CassandraBase.java | 91 + .../crud/datatypes/StudentCassandra.java | 484 ++++ .../crud/datatypes/StudentCassandraBase.java | 355 +++ .../StudentCassandraBigDecimalTest.java | 670 ++++++ .../StudentCassandraBigIntegerTest.java | 665 ++++++ .../StudentCassandraBooleanPrimitiveTest.java | 637 ++++++ .../StudentCassandraBooleanWrapperTest.java | 638 ++++++ .../StudentCassandraBytePrimitiveTest.java | 663 ++++++ .../StudentCassandraByteWrapperTest.java | 667 ++++++ .../datatypes/StudentCassandraCharTest.java | 663 ++++++ .../StudentCassandraCharacterTest.java | 666 ++++++ .../datatypes/StudentCassandraDateTest.java | 664 ++++++ .../StudentCassandraDoublePrimitiveTest.java | 663 ++++++ .../StudentCassandraDoubleWrapperTest.java | 663 ++++++ .../StudentCassandraFloatPrimitiveTest.java | 666 ++++++ .../StudentCassandraFloatWrapperTest.java | 663 ++++++ .../datatypes/StudentCassandraIntTest.java | 662 ++++++ .../StudentCassandraIntegerTest.java | 663 ++++++ .../StudentCassandraLongPrimitiveTest.java | 661 ++++++ .../StudentCassandraLongWrapperTest.java | 663 ++++++ .../StudentCassandraShortPrimitiveTest.java | 660 ++++++ .../StudentCassandraShortWrapperTest.java | 662 ++++++ .../StudentCassandraSqlDateTest.java | 665 ++++++ .../datatypes/StudentCassandraStringTest.java | 655 ++++++ .../crud/datatypes/StudentCassandraTest.java | 937 ++++++++ .../datatypes/StudentCassandraTimeTest.java | 665 ++++++ .../StudentCassandraTimestampTest.java | 668 ++++++ .../datatypes/StudentCassandraUUIDTest.java | 677 ++++++ .../crud/datatypes/StudentEntityDef.java | 264 +++ .../entities/StudentCassandraBigDecimal.java | 79 + .../entities/StudentCassandraBigInteger.java | 79 + .../StudentCassandraBooleanPrimitive.java | 76 + .../StudentCassandraBooleanWrapper.java | 76 + .../StudentCassandraBytePrimitive.java | 77 + .../entities/StudentCassandraByteWrapper.java | 77 + .../entities/StudentCassandraCalendar.java | 79 + .../entities/StudentCassandraChar.java | 77 + .../entities/StudentCassandraCharacter.java | 76 + .../entities/StudentCassandraDate.java | 79 + .../StudentCassandraDoublePrimitive.java | 77 + .../StudentCassandraDoubleWrapper.java | 77 + .../StudentCassandraFloatPrimitive.java | 76 + .../StudentCassandraFloatWrapper.java | 77 + .../entities/StudentCassandraInt.java | 77 + .../entities/StudentCassandraInteger.java | 76 + .../StudentCassandraLongPrimitive.java | 77 + .../entities/StudentCassandraLongWrapper.java | 77 + .../StudentCassandraShortPrimitive.java | 77 + .../StudentCassandraShortWrapper.java | 77 + .../entities/StudentCassandraSqlDate.java | 79 + .../entities/StudentCassandraString.java | 77 + .../entities/StudentCassandraTime.java | 79 + .../entities/StudentCassandraTimestamp.java | 79 + .../entities/StudentCassandraUUID.java | 79 + .../client/entity/CassandraUUIDEntity.java | 102 + .../com/impetus/client/entity/PromoCode.java | 51 + .../java/com/impetus/client/entity/Users.java | 87 + .../generatedId/CassandraGeneratedIdTest.java | 227 ++ .../entites/CassandraGeneratedIdDefault.java | 53 + .../CassandraGeneratedIdStrategyAuto.java | 57 + .../CassandraGeneratedIdStrategyIdentity.java | 71 + .../CassandraGeneratedIdStrategySequence.java | 57 + .../CassandraGeneratedIdStrategyTable.java | 59 + ...raGeneratedIdWithOutSequenceGenerator.java | 56 + ...andraGeneratedIdWithOutTableGenerator.java | 56 + ...andraGeneratedIdWithSequenceGenerator.java | 56 + ...assandraGeneratedIdWithTableGenerator.java | 57 + .../generatedId/entites/EmployeeAddress.java | 65 + .../generatedId/entites/EmployeeInfo.java | 84 + .../generatedId/entites/EmployeeInfoTest.java | 87 + .../impetus/client/junit/TestCassandra.java | 105 + .../persistence/CassandraBatchEntity.java | 98 + .../client/persistence/CassandraCli.java | 368 +++ .../client/persistence/CassandraEntity.java | 113 + .../persistence/CassandraEntitySample.java | 117 + .../EntityManagerFactoryImplTest.java | 197 ++ .../persistence/NativeQueryCQLV3Test.java | 291 +++ .../client/persistence/NativeQueryTest.java | 319 +++ .../NullableFieldAccessorTest.java | 178 ++ .../UpdateDeleteNamedQueryTest.java | 232 ++ .../CassandraPropertiesTest.java | 211 ++ .../CassandraSchemaManagerMTM.java | 162 ++ .../CassandraSchemaManagerMTMTest.java | 163 ++ .../CassandraSchemaManagerTest.java | 295 +++ ...sandraSchemaManagerValidateEntityTest.java | 155 ++ .../CassandraSchemaOperationTest.java | 536 +++++ .../CassanrdaGeneratedIdSchemaTest.java | 103 + .../client/schemamanager/entites/Actor.java | 127 ++ .../schemamanager/entites/ActorTest.java | 178 ++ .../CassandraEmbeddedPersonUniMto1.java | 163 ++ .../CassandraEntityAddressBi1To1FK.java | 108 + .../CassandraEntityAddressBi1To1PK.java | 134 ++ .../entites/CassandraEntityAddressBi1ToM.java | 111 + .../entites/CassandraEntityAddressBiMTo1.java | 111 + .../CassandraEntityAddressUni1To1.java | 82 + .../CassandraEntityAddressUni1To1PK.java | 107 + .../CassandraEntityAddressUni1ToM.java | 82 + .../CassandraEntityAddressUniMTo1.java | 81 + .../CassandraEntityHabitatUniMToM.java | 54 + .../CassandraEntityPersonBi1To1FK.java | 138 ++ .../CassandraEntityPersonBi1To1PK.java | 137 ++ .../entites/CassandraEntityPersonBi1ToM.java | 137 ++ .../entites/CassandraEntityPersonBiMTo1.java | 140 ++ .../entites/CassandraEntityPersonUni1To1.java | 163 ++ .../CassandraEntityPersonUni1To1PK.java | 137 ++ .../entites/CassandraEntityPersonUni1ToM.java | 165 ++ .../entites/CassandraEntityPersonUniMto1.java | 141 ++ .../CassandraEntityPersonnelUniMToM.java | 95 + .../entites/CassandraEntitySimple.java | 111 + .../entites/CassandraEntitySuper.java | 133 ++ .../entites/CassandraPersonalData.java | 127 ++ .../client/schemamanager/entites/Doctor.java | 96 + .../entites/InvalidCounterColumnEntity.java | 87 + .../client/schemamanager/entites/Movie.java | 79 + .../entites/ValidCounterColumnFamily.java | 88 + .../TwissandraSuperColumnDatatypeTest.java | 920 ++++++++ .../client/twitter/TwissandraTest.java | 243 ++ .../twitter/TwitterTestBaseCassandra.java | 601 +++++ .../client/twitter/dao/SuperDaoCassandra.java | 43 + .../client/twitter/dao/TwitterCassandra.java | 225 ++ .../twitter/dao/TwitterServiceCassandra.java | 501 ++++ .../entities/ExternalLinkCassandra.java | 105 + .../entities/PersonalDetailCassandra.java | 128 ++ .../twitter/entities/PreferenceCassandra.java | 105 + .../entities/ProfessionalDetailCassandra.java | 511 +++++ .../twitter/entities/TweetCassandra.java | 123 + .../twitter/entities/UserCassandra.java | 248 ++ .../twitter/utils/ExampleUtilsCassandra.java | 38 + .../kundera/query/KunderaQueryTest.java | 271 +++ .../kundera/query/ResultIteratorTest.java | 245 ++ .../cassandra/auth/SimpleAuthenticator.java | 275 +++ .../cassandra/auth/SimpleAuthority.java | 287 +++ .../test/resources/META-INF/persistence.xml | 333 +++ .../resources/META-INF/persistence_2_0.xsd | 354 +++ .../src/test/resources/access.properties | 3 + .../src/test/resources/cassandra.yaml | 644 ++++++ .../src/test/resources/ehcache-test.xml | 23 + .../resources/kundera-cassandra.properties | 4 + .../test/resources/kunderaConnectionTest.xml | 17 + .../src/test/resources/log4j.properties | 15 + .../src/test/resources/passwd.properties | 1 + src/kundera-core/pom.xml | 140 ++ .../java/com/impetus/kundera/Constants.java | 130 ++ .../java/com/impetus/kundera/DataWrapper.java | 40 + .../com/impetus/kundera/KunderaException.java | 63 + .../impetus/kundera/KunderaPersistence.java | 132 ++ .../KunderaPersistenceProviderUtil.java | 106 + .../kundera/KunderaPersistenceUnitUtil.java | 73 + .../kundera/PersistenceProperties.java | 93 + .../kundera/PersistenceUtilHelper.java | 260 +++ .../impetus/kundera/annotations/Index.java | 59 + .../java/com/impetus/kundera/cache/Cache.java | 53 + .../impetus/kundera/cache/CacheException.java | 66 + .../impetus/kundera/cache/CacheProvider.java | 77 + .../cache/ElementCollectionCacheManager.java | 227 ++ .../kundera/cache/NonOperationalCache.java | 107 + .../cache/NonOperationalCacheProvider.java | 100 + .../cache/ehcache/EhCacheProvider.java | 311 +++ .../kundera/cache/ehcache/EhCacheWrapper.java | 133 ++ .../AnnotationDiscoveryListener.java | 33 + .../classreading/ClassFileIterator.java | 116 + .../kundera/classreading/ClasspathReader.java | 311 +++ .../impetus/kundera/classreading/Filter.java | 35 + .../kundera/classreading/FilterImpl.java | 72 + .../kundera/classreading/JarFileIterator.java | 215 ++ .../impetus/kundera/classreading/Reader.java | 261 +++ .../classreading/ResourceIterator.java | 39 + .../ResourceReadingException.java | 66 + .../com/impetus/kundera/client/Client.java | 214 ++ .../impetus/kundera/client/ClientBase.java | 235 ++ .../client/ClientPropertiesSetter.java | 30 + .../kundera/client/ClientResolver.java | 165 ++ .../client/ClientResolverException.java | 67 + .../impetus/kundera/client/EnhanceEntity.java | 91 + .../configure/AbstractPropertyReader.java | 176 ++ .../AbstractSchemaConfiguration.java | 21 + .../configure/ClientFactoryConfiguraton.java | 63 + .../configure/ClientMetadataBuilder.java | 55 + .../kundera/configure/ClientProperties.java | 381 ++++ .../kundera/configure/Configuration.java | 36 + .../kundera/configure/Configurator.java | 68 + .../configure/MetamodelConfiguration.java | 498 ++++ .../PersistenceUnitConfiguration.java | 171 ++ ...PersistenceUnitConfigurationException.java | 54 + .../kundera/configure/PropertyReader.java | 32 + .../configure/SchemaConfiguration.java | 560 +++++ .../schema/CollectionColumnInfo.java | 92 + .../kundera/configure/schema/ColumnInfo.java | 151 ++ .../configure/schema/EmbeddedColumnInfo.java | 129 ++ .../kundera/configure/schema/IndexInfo.java | 102 + .../schema/SchemaGenerationException.java | 146 ++ .../kundera/configure/schema/TableInfo.java | 310 +++ .../schema/api/AbstractSchemaManager.java | 252 ++ .../configure/schema/api/SchemaManager.java | 50 + .../java/com/impetus/kundera/db/DataRow.java | 105 + .../impetus/kundera/db/RelationHolder.java | 84 + .../com/impetus/kundera/db/SearchResult.java | 90 + .../kundera/generator/AutoGenerator.java | 35 + .../impetus/kundera/generator/Generator.java | 27 + .../kundera/generator/IdentityGenerator.java | 38 + .../kundera/generator/SequenceGenerator.java | 38 + .../kundera/generator/TableGenerator.java | 39 + .../com/impetus/kundera/gis/SurfaceType.java | 25 + .../impetus/kundera/gis/geometry/Circle.java | 97 + .../kundera/gis/geometry/Coordinate.java | 64 + .../kundera/gis/geometry/Envelope.java | 75 + .../impetus/kundera/gis/geometry/Point.java | 82 + .../impetus/kundera/gis/geometry/Polygon.java | 54 + .../kundera/gis/geometry/Triangle.java | 41 + .../kundera/gis/query/GeospatialQuery.java | 27 + .../java/com/impetus/kundera/graph/Node.java | 765 +++++++ .../com/impetus/kundera/graph/NodeLink.java | 189 ++ .../impetus/kundera/graph/ObjectGraph.java | 96 + .../kundera/graph/ObjectGraphBuilder.java | 330 +++ .../kundera/graph/ObjectGraphUtils.java | 46 + .../kundera/index/DocumentIndexer.java | 398 ++++ .../java/com/impetus/kundera/index/Index.java | 64 + .../kundera/index/IndexCollection.java | 41 + .../impetus/kundera/index/IndexManager.java | 394 ++++ .../com/impetus/kundera/index/Indexer.java | 81 + .../kundera/index/IndexingException.java | 67 + .../impetus/kundera/index/LuceneIndexer.java | 659 ++++++ .../index/LuceneIndexingException.java | 64 + .../kundera/index/LuceneQueryUtils.java | 90 + .../impetus/kundera/index/lucene/Indexer.java | 93 + .../kundera/lifecycle/NodeStateContext.java | 126 + .../lifecycle/states/DetachedState.java | 124 + .../lifecycle/states/ManagedState.java | 243 ++ .../kundera/lifecycle/states/NodeState.java | 138 ++ .../lifecycle/states/RemovedState.java | 157 ++ .../lifecycle/states/TransientState.java | 134 ++ .../impetus/kundera/loader/ClientFactory.java | 53 + .../loader/ClientLifeCycleManager.java | 45 + .../kundera/loader/ClientLoaderException.java | 67 + .../impetus/kundera/loader/CoreLoader.java | 47 + .../kundera/loader/GenericClientFactory.java | 339 +++ .../KunderaAuthenticationException.java | 67 + .../loader/MetamodelLoaderException.java | 62 + .../loader/PersistenceLoaderException.java | 67 + .../kundera/loader/PersistenceXMLLoader.java | 631 ++++++ .../metadata/KunderaMetadataManager.java | 162 ++ .../kundera/metadata/MetadataBuilder.java | 179 ++ .../kundera/metadata/MetadataProcessor.java | 38 + .../kundera/metadata/MetadataUtils.java | 632 ++++++ .../model/ApplicationLoaderException.java | 42 + .../metadata/model/ApplicationMetadata.java | 408 ++++ .../metadata/model/ClientMetadata.java | 114 + .../kundera/metadata/model/Column.java | 99 + .../kundera/metadata/model/CoreMetadata.java | 52 + .../metadata/model/EmbeddedColumn.java | 118 + .../metadata/model/EntityMetadata.java | 752 ++++++ .../kundera/metadata/model/IdDiscriptor.java | 85 + .../metadata/model/JoinTableMetadata.java | 162 ++ .../metadata/model/KunderaMetadata.java | 96 + .../kundera/metadata/model/MetamodelImpl.java | 429 ++++ .../model/PersistenceUnitMetadata.java | 589 +++++ .../kundera/metadata/model/PropertyIndex.java | 185 ++ .../kundera/metadata/model/Relation.java | 390 ++++ .../model/SequenceGeneratorDiscriptor.java | 102 + .../model/TableGeneratorDiscriptor.java | 154 ++ .../model/attributes/AbstractAttribute.java | 235 ++ .../attributes/AbstractPluralAttribute.java | 108 + .../model/attributes/AttributeType.java | 63 + .../DefaultCollectionAttribute.java | 100 + .../attributes/DefaultListAttribute.java | 97 + .../model/attributes/DefaultMapAttribute.java | 139 ++ .../model/attributes/DefaultSetAttribute.java | 95 + .../attributes/DefaultSingularAttribute.java | 162 ++ .../model/type/AbstractIdentifiableType.java | 244 ++ .../model/type/AbstractManagedType.java | 1047 +++++++++ .../metadata/model/type/AbstractType.java | 73 + .../metadata/model/type/DefaultBasicType.java | 45 + .../model/type/DefaultEmbeddableType.java | 45 + .../model/type/DefaultEntityType.java | 78 + .../model/type/DefaultMappedSuperClass.java | 45 + .../AbstractEntityFieldProcessor.java | 155 ++ .../CacheableAnnotationProcessor.java | 65 + .../processor/EntityListenersProcessor.java | 247 ++ .../processor/GeneratedValueProcessor.java | 104 + .../metadata/processor/IndexProcessor.java | 268 +++ .../metadata/processor/MetaModelBuilder.java | 793 +++++++ .../metadata/processor/TableProcessor.java | 301 +++ .../ManyToManyRelationMetadataProcessor.java | 192 ++ .../ManyToOneRelationMetadataProcessor.java | 101 + .../OneToManyRelationMetadataProcessor.java | 124 + .../OneToOneRelationMetadataProcessor.java | 109 + .../relation/RelationMetadataProcessor.java | 40 + .../RelationMetadataProcessorFactory.java | 75 + .../metadata/validator/EntityValidator.java | 42 + .../validator/EntityValidatorImpl.java | 240 ++ .../InvalidEntityDefinitionException.java | 48 + .../persistence/AbstractEntityReader.java | 544 +++++ .../persistence/AssociationBuilder.java | 441 ++++ .../kundera/persistence/Coordinator.java | 110 + .../DefaultTransactionResource.java | 155 ++ .../persistence/EntityManagerFactoryImpl.java | 416 ++++ .../persistence/EntityManagerImpl.java | 995 ++++++++ .../persistence/EntityManagerSession.java | 225 ++ .../kundera/persistence/EntityReader.java | 91 + .../persistence/EntityReaderException.java | 63 + .../kundera/persistence/IdGenerator.java | 183 ++ .../persistence/KunderaEntityTransaction.java | 146 ++ .../KunderaTransactionException.java | 64 + .../persistence/PersistenceDelegator.java | 984 ++++++++ .../persistence/PersistenceValidator.java | 61 + .../kundera/persistence/ResourceManager.java | 35 + .../persistence/TransactionBinder.java | 40 + .../persistence/TransactionResource.java | 73 + .../kundera/persistence/api/Batcher.java | 56 + .../persistence/context/CacheBase.java | 194 ++ .../context/ElementCollectionCache.java | 26 + .../persistence/context/EmbeddedCache.java | 26 + .../kundera/persistence/context/EventLog.java | 83 + .../persistence/context/EventLogQueue.java | 181 ++ .../persistence/context/FlushManager.java | 526 +++++ .../persistence/context/MainCache.java | 26 + .../persistence/context/PersistenceCache.java | 193 ++ .../context/PersistenceCacheManager.java | 91 + .../context/TransactionalCache.java | 26 + .../context/jointable/JoinTableData.java | 219 ++ .../persistence/event/CallbackMethod.java | 44 + .../event/EntityEventDispatcher.java | 69 + .../event/EventListenerException.java | 60 + .../event/ExternalCallbackMethod.java | 82 + .../event/InternalCallbackMethod.java | 90 + .../jta/KunderaJTAUserTransaction.java | 273 +++ .../persistence/jta/KunderaTransaction.java | 199 ++ .../jta/UserTransactionFactory.java | 103 + .../property/PropertyAccessException.java | 60 + .../kundera/property/PropertyAccessor.java | 93 + .../property/PropertyAccessorFactory.java | 186 ++ .../property/PropertyAccessorHelper.java | 552 +++++ .../property/accessor/BigDecimalAccessor.java | 115 + .../property/accessor/BigIntegerAccessor.java | 98 + .../property/accessor/BooleanAccessor.java | 107 + .../property/accessor/ByteAccessor.java | 127 ++ .../property/accessor/CalendarAccessor.java | 131 ++ .../property/accessor/CharAccessor.java | 131 ++ .../property/accessor/DateAccessor.java | 260 +++ .../property/accessor/DoubleAccessor.java | 136 ++ .../property/accessor/EnumAccessor.java | 112 + .../property/accessor/FloatAccessor.java | 131 ++ .../property/accessor/IntegerAccessor.java | 110 + .../property/accessor/LongAccessor.java | 112 + .../property/accessor/ObjectAccessor.java | 232 ++ .../property/accessor/PointAccessor.java | 117 + .../property/accessor/SQLDateAccessor.java | 142 ++ .../property/accessor/SQLTimeAccessor.java | 162 ++ .../accessor/SQLTimestampAccessor.java | 158 ++ .../property/accessor/ShortAccessor.java | 117 + .../property/accessor/StringAccessor.java | 113 + .../property/accessor/UUIDAccessor.java | 198 ++ .../impetus/kundera/proxy/KunderaProxy.java | 29 + .../proxy/LazyInitializationException.java | 45 + .../kundera/proxy/LazyInitializer.java | 114 + .../kundera/proxy/LazyInitializerFactory.java | 75 + .../impetus/kundera/proxy/ProxyHelper.java | 87 + .../proxy/cglib/CglibLazyInitializer.java | 495 ++++ .../cglib/CglibLazyInitializerFactory.java | 107 + .../proxy/collection/AbstractProxyBase.java | 136 ++ .../collection/AbstractProxyCollection.java | 257 +++ .../proxy/collection/ProxyCollection.java | 77 + .../kundera/proxy/collection/ProxyList.java | 314 +++ .../kundera/proxy/collection/ProxyMap.java | 227 ++ .../kundera/proxy/collection/ProxySet.java | 132 ++ .../kundera/query/IResultIterator.java | 39 + .../kundera/query/JPQLParseException.java | 51 + .../impetus/kundera/query/KunderaQuery.java | 1318 +++++++++++ .../kundera/query/KunderaQueryParser.java | 575 +++++ .../kundera/query/KunderaTypedQuery.java | 474 ++++ .../impetus/kundera/query/LuceneQuery.java | 182 ++ .../java/com/impetus/kundera/query/Query.java | 53 + .../kundera/query/QueryHandlerException.java | 63 + .../com/impetus/kundera/query/QueryImpl.java | 1087 +++++++++ .../impetus/kundera/query/QueryResolver.java | 147 ++ .../com/impetus/kundera/service/Host.java | 76 + .../kundera/service/HostConfiguration.java | 129 ++ .../policy/LeastActiveBalancingPolicy.java | 37 + .../service/policy/LoadBalancingPolicy.java | 37 + .../kundera/service/policy/RetryService.java | 36 + .../policy/RoundRobinBalancingPolicy.java | 72 + .../com/impetus/kundera/utils/DeepEquals.java | 519 +++++ .../utils/InvalidConfigurationException.java | 59 + .../kundera/utils/KunderaCoreUtils.java | 51 + .../kundera/utils/KunderaThreadFactory.java | 60 + .../impetus/kundera/utils/ObjectUtils.java | 418 ++++ .../impetus/kundera/utils/ReflectUtils.java | 203 ++ .../javax.persistence.spi.PersistenceProvider | 1 + .../src/main/resources/persistence_1_0.xsd | 260 +++ .../src/main/resources/persistence_2_0.xsd | 227 ++ .../com/impetus/kundera/AllTestSuites.java | 45 + .../impetus/kundera/CoreTestUtilities.java | 132 ++ .../kundera/EntityManagerImplTest.java | 214 ++ .../kundera/EntityTransactionTest.java | 256 +++ .../KunderaPersistenceProviderUtilTest.java | 73 + .../kundera/KunderaPersistenceTest.java | 70 + .../KunderaPersistenceUnitUtilTest.java | 85 + .../kundera/PersistenceUtilHelperTest.java | 117 + .../ElementCollectionCacheManagerTest.java | 69 + .../cache/NonOperationCacheProviderTest.java | 49 + .../cache/NonOperationalCacheTest.java | 58 + .../cache/ehcache/EhCacheProviderTest.java | 211 ++ .../cache/ehcache/KunderaQueryParserTest.java | 216 ++ .../classreading/ClasspathReaderTest.java | 121 + .../kundera/classreading/DataRowTest.java | 60 + .../kundera/classreading/FilterTest.java | 64 + .../classreading/RelationHolderTest.java | 50 + .../classreading/SearchResultTest.java | 51 + .../kundera/client/ClientResolverTest.java | 61 + .../kundera/client/CoreTestClient.java | 209 ++ .../kundera/client/CoreTestClientFactory.java | 122 + .../client/CoreTestClientNoGenerator.java | 184 ++ .../impetus/kundera/client/DummyDatabase.java | 74 + .../impetus/kundera/client/DummySchema.java | 74 + .../impetus/kundera/client/DummyTable.java | 75 + .../kundera/client/EnhanceEntityTest.java | 46 + .../configure/AbstractPropertyReaderTest.java | 126 + .../kundera/configure/ConfiguratorTest.java | 197 ++ .../configure/CoreEntityAddressUni1To1.java | 83 + .../configure/CoreEntityAddressUni1ToM.java | 83 + .../configure/CoreEntityAddressUniMTo1.java | 82 + .../configure/CoreEntityPersionUniMto1.java | 164 ++ .../configure/CoreEntityPersonUni1To1.java | 164 ++ .../configure/CoreEntityPersonUni1ToM.java | 166 ++ .../kundera/configure/CoreEntitySimple.java | 108 + .../kundera/configure/CoreEntitySuper.java | 137 ++ .../configure/DummyPropertyReader.java | 85 + .../kundera/configure/PersonalData.java | 130 ++ .../configure/SchemaConfigurationTest.java | 215 ++ .../configure/schema/ColumnInfoTest.java | 51 + .../schema/EmbeddedColumnInfoTest.java | 63 + .../configure/schema/IndexInfoTest.java | 63 + .../configure/schema/TableInfoTest.java | 78 + .../schema/api/CoreSchemaManager.java | 142 ++ .../schema/api/SchemaManagerTest.java | 177 ++ .../BigDecimalDataGenerator.java | 33 + .../BigIntegerDataGenerator.java | 34 + .../datagenerator/BooleanDataGenerator.java | 34 + .../datagenerator/ByteDataGenerator.java | 35 + .../datagenerator/CalendarDataGenerator.java | 33 + .../datagenerator/CharDataGenerator.java | 36 + .../datagenerator/DataGenerator.java | 27 + .../datagenerator/DataGeneratorFactory.java | 90 + .../datagenerator/DateDataGenerator.java | 40 + .../datagenerator/DoubleDataGenerator.java | 36 + .../datagenerator/FloatDataGenerator.java | 36 + .../datagenerator/IntegerDataGenerator.java | 31 + .../datagenerator/LongDataGenerator.java | 32 + .../datagenerator/ShortDataGenerator.java | 31 + .../datagenerator/SqlDateDataGenerator.java | 38 + .../datagenerator/SqlTimeDataGenerator.java | 38 + .../SqlTimestampDataGenerator.java | 38 + .../datagenerator/StringDataGenerator.java | 35 + .../datagenerator/UUIDDataGenerator.java | 42 + .../kundera/entity/PersonalDetail.java | 125 + .../impetus/kundera/entity/PersonnelDTO.java | 134 ++ .../com/impetus/kundera/entity/Tweet.java | 117 + .../kundera/entity/album/AlbumBi_1_1_1_1.java | 153 ++ .../kundera/entity/album/AlbumBi_1_1_1_M.java | 158 ++ .../kundera/entity/album/AlbumBi_1_M_1_M.java | 160 ++ .../kundera/entity/album/AlbumBi_1_M_M_M.java | 161 ++ .../kundera/entity/album/AlbumBi_M_1_1_M.java | 157 ++ .../kundera/entity/album/AlbumBi_M_M_1_1.java | 156 ++ .../kundera/entity/album/AlbumBi_M_M_M_M.java | 159 ++ .../entity/album/AlbumUni_1_1_1_1.java | 132 ++ .../entity/album/AlbumUni_1_1_1_M.java | 138 ++ .../entity/album/AlbumUni_1_1_M_1.java | 132 ++ .../entity/album/AlbumUni_1_M_1_M.java | 139 ++ .../entity/album/AlbumUni_1_M_M_M.java | 137 ++ .../entity/album/AlbumUni_M_1_1_M.java | 138 ++ .../entity/album/AlbumUni_M_M_1_1.java | 132 ++ .../entity/album/AlbumUni_M_M_M_M.java | 137 ++ .../kundera/entity/photo/PhotoBi_1_1_1_1.java | 127 ++ .../kundera/entity/photo/PhotoBi_1_1_1_M.java | 131 ++ .../kundera/entity/photo/PhotoBi_1_M_1_M.java | 131 ++ .../kundera/entity/photo/PhotoBi_1_M_M_M.java | 146 ++ .../kundera/entity/photo/PhotoBi_M_1_1_M.java | 131 ++ .../kundera/entity/photo/PhotoBi_M_M_1_1.java | 127 ++ .../kundera/entity/photo/PhotoBi_M_M_M_M.java | 131 ++ .../entity/photo/PhotoUni_1_1_1_1.java | 103 + .../entity/photo/PhotoUni_1_1_1_M.java | 106 + .../entity/photo/PhotoUni_1_1_M_1.java | 103 + .../entity/photo/PhotoUni_1_M_1_M.java | 105 + .../entity/photo/PhotoUni_1_M_M_M.java | 105 + .../entity/photo/PhotoUni_M_1_1_M.java | 105 + .../entity/photo/PhotoUni_M_M_1_1.java | 103 + .../entity/photo/PhotoUni_M_M_M_M.java | 105 + .../photographer/PhotographerBi_1_1_1_1.java | 101 + .../photographer/PhotographerBi_1_1_1_M.java | 101 + .../photographer/PhotographerBi_1_M_1_M.java | 176 ++ .../photographer/PhotographerBi_1_M_M_M.java | 116 + .../photographer/PhotographerBi_M_1_1_M.java | 101 + .../photographer/PhotographerBi_M_M_1_1.java | 107 + .../photographer/PhotographerBi_M_M_M_M.java | 107 + .../photographer/PhotographerUni_1_1_1_1.java | 101 + .../photographer/PhotographerUni_1_1_1_M.java | 94 + .../photographer/PhotographerUni_1_1_M_1.java | 101 + .../photographer/PhotographerUni_1_M_1_M.java | 179 ++ .../photographer/PhotographerUni_1_M_M_M.java | 118 + .../photographer/PhotographerUni_M_1_1_M.java | 101 + .../photographer/PhotographerUni_M_M_1_1.java | 107 + .../photographer/PhotographerUni_M_M_M_M.java | 107 + .../kundera/gis/geometry/CircleTest.java | 67 + .../kundera/gis/geometry/EnvelopeTest.java | 56 + .../kundera/gis/geometry/PointTest.java | 60 + .../kundera/gis/geometry/PolygonTest.java | 67 + .../kundera/gis/geometry/TriangleTest.java | 46 + .../impetus/kundera/graph/BillingCounter.java | 85 + .../kundera/graph/ObjectGraphTest.java | 106 + .../kundera/graph/ObjectGraphUtilsTest.java | 78 + .../java/com/impetus/kundera/graph/Store.java | 117 + .../impetus/kundera/graph/StoreBuilder.java | 74 + .../kundera/index/IndexManagerTest.java | 141 ++ .../kundera/index/LuceneIndexerTest.java | 123 + .../lifecycle/states/DetachedStateTest.java | 275 +++ .../lifecycle/states/ManagedStateTest.java | 353 +++ .../lifecycle/states/NodeStateTest.java | 144 ++ .../lifecycle/states/RemovedStateTest.java | 322 +++ .../lifecycle/states/TransientStateTest.java | 274 +++ .../loader/GenericClientFactoryTest.java | 104 + .../metadata/KunderaMetadataManagerTest.java | 85 + .../kundera/metadata/MetadataBuilderTest.java | 54 + .../kundera/metadata/MetadataUtilsTest.java | 136 ++ .../metadata/entities/AssociationEntity.java | 93 + .../CollectionTypeAssociationEntity.java | 70 + .../metadata/entities/EmbeddableEntity.java | 51 + .../entities/EmbeddableEntityTwo.java | 71 + .../entities/EmbeddableTransientEntity.java | 56 + .../entities/EmbeddedIdOwnerEntity.java | 72 + .../metadata/entities/IDClassEntity.java | 63 + .../metadata/entities/IDClassOwnerEntity.java | 74 + .../entities/ListTypeAssociationEntity.java | 70 + .../entities/MapTypeAssociationEntity.java | 70 + .../metadata/entities/MappedSuperClass.java | 69 + .../metadata/entities/OToMOwnerEntity.java | 119 + .../metadata/entities/OToOOwnerEntity.java | 117 + .../metadata/entities/PluralOwnerType.java | 144 ++ .../entities/RootMappedSuperClass.java | 53 + .../metadata/entities/SampleEntity.java | 99 + .../entities/SetTypeAssociationEntity.java | 70 + .../metadata/entities/SingularEntity.java | 95 + .../entities/SingularEntityEmbeddable.java | 136 ++ .../kundera/metadata/entities/SubClassA.java | 95 + .../kundera/metadata/entities/SubClassB.java | 94 + .../metadata/entities/TransientEntity.java | 102 + .../entities/bi/AssociationBiEntity.java | 131 ++ .../entities/bi/OToOOwnerBiEntity.java | 117 + .../kundera/metadata/model/Department.java | 134 ++ .../kundera/metadata/model/Employe.java | 137 ++ .../metadata/model/EntityMetadataTest.java | 175 ++ .../kundera/metadata/model/KunderaUser.java | 145 ++ .../model/PersistenceUnitMetadataTest.java | 92 + .../model/ProcessAnnotationsTest.java | 171 ++ .../kundera/metadata/model/TweetKundera.java | 122 + .../metadata/processor/AttributeTypeTest.java | 49 + .../metadata/processor/EntitySample.java | 87 + ...etaModelBuilderForTransientEntityTest.java | 197 ++ .../processor/MetaModelBuilderTest.java | 978 ++++++++ .../processor/TableProcessorTest.java | 105 + .../relation/RelationProcessorTest.java | 144 ++ .../validator/EntityValidatorImplTest.java | 183 ++ .../validator/EntityWithMultipleId.java | 66 + .../validator/EntityWithOutConstructor.java | 43 + .../metadata/validator/EntityWithOutId.java | 48 + .../EntityWithOutTableAnnotation.java | 46 + .../validator/GeneratedIdDefault.java | 53 + .../validator/GeneratedIdStrategyAuto.java | 57 + .../GeneratedIdStrategyIdentity.java | 56 + .../GeneratedIdStrategySequence.java | 57 + .../validator/GeneratedIdStrategyTable.java | 59 + .../GeneratedIdWithInvalidGenerator.java | 57 + .../validator/GeneratedIdWithNoGenerator.java | 55 + .../GeneratedIdWithOutSequenceGenerator.java | 56 + .../GeneratedIdWithOutTableGenerator.java | 56 + .../GeneratedIdWithSequenceGenerator.java | 56 + .../GeneratedIdWithTableGenerator.java | 57 + .../persistence/AssociationBuilderTest.java | 124 + .../persistence/EntityManagerSessionTest.java | 118 + .../kundera/persistence/EntityReaderTest.java | 478 ++++ .../persistence/FlushStackManagerTest.java | 687 ++++++ .../kundera/persistence/IdGeneratorTest.java | 180 ++ .../JPAImplementationTestSuite.java | 44 + .../persistence/ObjectGraphBuilderTest.java | 143 ++ .../persistence/PersistenceCacheTest.java | 147 ++ .../persistence/PersistenceDelegatorTest.java | 394 ++++ .../PersistenceUnitLoaderTest.java | 103 + .../persistence/context/FlushStackTest.java | 70 + .../context/PersistenceCacheManagerTest.java | 83 + .../persistence/event/AddressEntity.java | 112 + .../event/AddressEntityWithList.java | 110 + .../event/EntityEventDispatcherTest.java | 143 ++ .../event/PersonEventDispatch.java | 136 ++ .../persistence/event/PersonHandler.java | 35 + .../jta/KunderaJTAUserTransactionTest.java | 256 +++ .../jta/KunderaTransactionTest.java | 90 + .../impetus/kundera/polyglot/dao/BaseDao.java | 66 + .../polyglot/dao/PersonAddressDaoImpl.java | 147 ++ .../polyglot/entities/AddressB11FK.java | 73 + .../polyglot/entities/AddressB11PK.java | 86 + .../kundera/polyglot/entities/AddressB1M.java | 75 + .../kundera/polyglot/entities/AddressBM1.java | 75 + .../kundera/polyglot/entities/AddressBMM.java | 75 + .../polyglot/entities/AddressU11FK.java | 58 + .../polyglot/entities/AddressU11PK.java | 71 + .../kundera/polyglot/entities/AddressU1M.java | 58 + .../kundera/polyglot/entities/AddressUM1.java | 57 + .../kundera/polyglot/entities/AddressUMM.java | 58 + .../polyglot/entities/PersonB11FK.java | 76 + .../polyglot/entities/PersonB11PK.java | 75 + .../kundera/polyglot/entities/PersonB1M.java | 77 + .../kundera/polyglot/entities/PersonBM1.java | 75 + .../kundera/polyglot/entities/PersonBMM.java | 79 + .../polyglot/entities/PersonU11FK.java | 76 + .../polyglot/entities/PersonU11PK.java | 76 + .../kundera/polyglot/entities/PersonU1M.java | 77 + .../kundera/polyglot/entities/PersonUM1.java | 76 + .../kundera/polyglot/entities/PersonUMM.java | 79 + .../polyglot/entities/PersonUMMByMap.java | 81 + .../polyglot/tests/MMBPolyglotTest.java | 202 ++ .../polyglot/tests/MMUPolyglotTest.java | 282 +++ .../polyglot/tests/MOBPolyglotTest.java | 178 ++ .../polyglot/tests/MOUPolyglotTest.java | 217 ++ .../polyglot/tests/OMBPolyglotTest.java | 199 ++ .../polyglot/tests/OMUPolyglotTest.java | 222 ++ .../polyglot/tests/OOBPolyglotTest.java | 206 ++ .../polyglot/tests/OOUPolyglotTest.java | 229 ++ .../polyglot/tests/PersonAddressTestBase.java | 80 + .../property/PropertyAccessorHelperTest.java | 507 +++++ .../accessor/BigDecimalAccessorTest.java | 141 ++ .../accessor/BigIntegerAccessorTest.java | 138 ++ .../accessor/BooleanAccessorTest.java | 139 ++ .../property/accessor/ByteAccessorTest.java | 133 ++ .../accessor/CalendarAccessorTest.java | 151 ++ .../property/accessor/CharAccessorTest.java | 108 + .../property/accessor/DateAccessorTest.java | 142 ++ .../property/accessor/DoubleAccessorTest.java | 139 ++ .../property/accessor/EnumAccessorTest.java | 209 ++ .../property/accessor/FloatAccessorTest.java | 138 ++ .../accessor/IntegerAccessorTest.java | 139 ++ .../property/accessor/LongAccessorTest.java | 121 + .../property/accessor/ObjectAccessorTest.java | 147 ++ .../property/accessor/PersonalDetail.java | 137 ++ .../property/accessor/PointAccessorTest.java | 149 ++ .../accessor/SQLDateAccessorTest.java | 148 ++ .../accessor/SQLTimeAccessorTest.java | 154 ++ .../accessor/SQLTimestampAccessorTest.java | 143 ++ .../property/accessor/ShortAccessorTest.java | 117 + .../property/accessor/StringAccessorTest.java | 137 ++ .../property/accessor/UUIDAccessorTest.java | 137 ++ .../CglibLazyInitializerFactoryTest.java | 92 + .../proxy/cglib/CglibLazyInitializerTest.java | 160 ++ .../proxy/collection/ProxyListTest.java | 137 ++ .../proxy/collection/ProxyMapTest.java | 154 ++ .../proxy/collection/ProxySetTest.java | 121 + .../impetus/kundera/query/CoreIndexer.java | 81 + .../com/impetus/kundera/query/CoreQuery.java | 128 ++ .../kundera/query/CoreTestEntityReader.java | 54 + .../kundera/query/KunderaQueryTest.java | 414 ++++ .../kundera/query/KunderaTypedQueryTest.java | 196 ++ .../kundera/query/LuceneQueryTest.java | 104 + .../com/impetus/kundera/query/Person.java | 154 ++ .../com/impetus/kundera/query/PersonTest.java | 306 +++ .../kundera/query/QueryExceptionTest.java | 275 +++ .../impetus/kundera/query/QueryImplTest.java | 502 ++++ .../service/CoreHostConfiguration.java | 74 + .../service/HostconfigurationTest.java | 161 ++ .../policy/RoundRobinBalancingPolicyTest.java | 88 + .../impetus/kundera/utils/DeepEqualsTest.java | 608 +++++ .../kundera/utils/KunderaCoreUtilsTest.java | 60 + .../utils/KunderaThreadFactoryTest.java | 51 + .../kundera/utils/LuceneCleanupUtilities.java | 68 + .../ObjectUtilsCloneBidirectionalM2MTest.java | 328 +++ .../ObjectUtilsCloneBidirectionalTest.java | 336 +++ .../ObjectUtilsCloneUnidirectionalTest.java | 357 +++ .../kundera/utils/ReflectUtilsTest.java | 69 + .../test/resources/META-INF/persistence.xml | 186 ++ .../resources/META-INF/persistence_2_0.xsd | 354 +++ .../src/test/resources/ehcache-test.xml | 13 + .../src/test/resources/kunderaTest.xml | 165 ++ .../test/resources/kunderaTestDataType.xml | 42 + .../src/test/resources/log4j.properties | 15 + src/kundera-hbase/pom.xml | 156 ++ .../com/impetus/client/hbase/HBaseClient.java | 832 +++++++ .../client/hbase/HBaseClientFactory.java | 189 ++ .../client/hbase/HBaseClientProperties.java | 59 + .../impetus/client/hbase/HBaseConstants.java | 31 + .../com/impetus/client/hbase/HBaseData.java | 108 + .../client/hbase/HBaseEntityReader.java | 62 + .../java/com/impetus/client/hbase/Reader.java | 101 + .../java/com/impetus/client/hbase/Writer.java | 165 ++ .../client/hbase/admin/DataHandler.java | 185 ++ .../client/hbase/admin/HBaseDataHandler.java | 1167 ++++++++++ .../hbase/config/HBasePropertyReader.java | 163 ++ .../client/hbase/query/HBaseQuery.java | 572 +++++ .../client/hbase/query/ResultIterator.java | 296 +++ .../schemamanager/HBaseSchemaManager.java | 434 ++++ .../client/hbase/service/HBaseReader.java | 421 ++++ .../client/hbase/service/HBaseWriter.java | 360 +++ .../client/hbase/utils/HBaseUtils.java | 185 ++ .../recommendation/hbase/model/BookInfo.java | 162 ++ .../hbase/model/CitySimilarity.java | 66 + .../hbase/model/CitySimilarityTest.java | 186 ++ .../hbase/model/UserAndPassword.java | 96 + .../hbase/model/UserAndPasswordTest.java | 198 ++ .../recommendation/hbase/model/UserInfo.java | 130 ++ .../client/hbase/config/HBaseEntity.java | 88 + .../client/hbase/config/HBaseUser.java | 80 + .../client/hbase/config/HBaseUserTest.java | 129 ++ .../impetus/client/hbase/crud/BaseTest.java | 298 +++ .../hbase/crud/HBaseBatchProcessorTest.java | 160 ++ .../client/hbase/crud/HBaseIdQueryTest.java | 482 ++++ .../com/impetus/client/hbase/crud/Human.java | 62 + .../impetus/client/hbase/crud/HumanTest.java | 83 + .../client/hbase/crud/HumansPrivatePhoto.java | 58 + .../com/impetus/client/hbase/crud/Month.java | 6 + .../hbase/crud/PersonBatchHBaseEntity.java | 124 + .../client/hbase/crud/PersonHBase.java | 146 ++ .../client/hbase/crud/PersonHBaseTest.java | 242 ++ .../crud/association/AddressOTOHbase.java | 45 + .../association/HbaseAssociationTest.java | 94 + .../crud/association/PersonOTOHbase.java | 159 ++ .../client/hbase/crud/datatypes/Base.java | 47 + .../hbase/crud/datatypes/StudentBase.java | 361 +++ .../crud/datatypes/StudentEntityDef.java | 264 +++ .../hbase/crud/datatypes/StudentHBase.java | 474 ++++ .../datatypes/StudentHBaseBigDecimalTest.java | 572 +++++ .../datatypes/StudentHBaseBigIntegerTest.java | 575 +++++ .../StudentHBaseBooleanPrimitiveTest.java | 557 +++++ .../StudentHBaseBooleanWrapperTest.java | 554 +++++ .../StudentHBaseBytePrimitiveTest.java | 583 +++++ .../StudentHBaseByteWrapperTest.java | 582 +++++ .../datatypes/StudentHBaseCalendarTest.java | 516 +++++ .../crud/datatypes/StudentHBaseCharTest.java | 579 +++++ .../datatypes/StudentHBaseCharacterTest.java | 582 +++++ .../crud/datatypes/StudentHBaseDateTest.java | 580 +++++ .../StudentHBaseDoublePrimitiveTest.java | 580 +++++ .../StudentHBaseDoubleWrapperTest.java | 579 +++++ .../StudentHBaseFloatPrimitiveTest.java | 579 +++++ .../StudentHBaseFloatWrapperTest.java | 578 +++++ .../crud/datatypes/StudentHBaseIntTest.java | 603 +++++ .../datatypes/StudentHBaseIntegerTest.java | 582 +++++ .../StudentHBaseLongPrimitiveTest.java | 582 +++++ .../StudentHBaseLongWrapperTest.java | 581 +++++ .../StudentHBaseShortPrimitiveTest.java | 580 +++++ .../StudentHBaseShortWrapperTest.java | 579 +++++ .../datatypes/StudentHBaseSqlDateTest.java | 583 +++++ .../datatypes/StudentHBaseStringTest.java | 571 +++++ .../crud/datatypes/StudentHBaseTest.java | 471 ++++ .../crud/datatypes/StudentHBaseTimeTest.java | 582 +++++ .../datatypes/StudentHBaseTimestampTest.java | 582 +++++ .../crud/datatypes/StudentHBaseUUIDTest.java | 580 +++++ .../hbase/crud/datatypes/ZkShutDownTest.java | 39 + .../entities/StudentHBaseBigDecimal.java | 75 + .../entities/StudentHBaseBigInteger.java | 75 + .../StudentHBaseBooleanPrimitive.java | 72 + .../entities/StudentHBaseBooleanWrapper.java | 72 + .../entities/StudentHBaseBytePrimitive.java | 73 + .../entities/StudentHBaseByteWrapper.java | 73 + .../entities/StudentHBaseCalendar.java | 75 + .../datatypes/entities/StudentHBaseChar.java | 73 + .../entities/StudentHBaseCharacter.java | 72 + .../datatypes/entities/StudentHBaseDate.java | 75 + .../entities/StudentHBaseDoublePrimitive.java | 73 + .../entities/StudentHBaseDoubleWrapper.java | 73 + .../entities/StudentHBaseFloatPrimitive.java | 72 + .../entities/StudentHBaseFloatWrapper.java | 73 + .../datatypes/entities/StudentHBaseInt.java | 73 + .../entities/StudentHBaseInteger.java | 72 + .../entities/StudentHBaseLongPrimitive.java | 73 + .../entities/StudentHBaseLongWrapper.java | 73 + .../entities/StudentHBaseShortPrimitive.java | 73 + .../entities/StudentHBaseShortWrapper.java | 73 + .../entities/StudentHBaseSqlDate.java | 75 + .../entities/StudentHBaseString.java | 73 + .../datatypes/entities/StudentHBaseTime.java | 75 + .../entities/StudentHBaseTimestamp.java | 75 + .../datatypes/entities/StudentHBaseUUID.java | 75 + .../crud/embedded/EmbeddedEntityTest.java | 243 ++ .../hbase/crud/embedded/NetstatData.java | 217 ++ .../hbase/crud/embedded/NetstatDataId.java | 93 + .../generatedId/HBaseGeneratedIdTest.java | 226 ++ .../entites/HBaseGeneratedIdDefault.java | 53 + .../entites/HBaseGeneratedIdStrategyAuto.java | 57 + .../HBaseGeneratedIdStrategyIdentity.java | 56 + .../HBaseGeneratedIdStrategySequence.java | 57 + .../HBaseGeneratedIdStrategyTable.java | 59 + ...seGeneratedIdWithOutSequenceGenerator.java | 56 + ...HBaseGeneratedIdWithOutTableGenerator.java | 56 + ...HBaseGeneratedIdWithSequenceGenerator.java | 56 + .../HBaseGeneratedIdWithTableGenerator.java | 57 + .../impetus/client/hbase/junits/HBaseCli.java | 341 +++ .../HBaseEntityAddressUni1To1.java | 83 + .../HBaseEntityAddressUni1To1PK.java | 107 + .../HBaseEntityAddressUni1ToM.java | 82 + .../HBaseEntityAddressUniMTo1.java | 81 + .../HBaseEntityPersonUni1To1.java | 163 ++ .../HBaseEntityPersonUni1To1PK.java | 137 ++ .../HBaseEntityPersonUni1ToM.java | 165 ++ .../HBaseEntityPersonUniMto1.java | 163 ++ .../schemaManager/HBaseEntitySimple.java | 108 + .../hbase/schemaManager/HBaseEntitySuper.java | 133 ++ .../HBaseGeneratedIdSchemaTest.java | 82 + .../schemaManager/HBasePersonalData.java | 128 ++ .../schemaManager/HBaseSchemaManagerTest.java | 262 +++ .../HBaseSchemaOperationTest.java | 370 +++ .../client/query/ResultIteratorTest.java | 217 ++ .../java/com/impetus/client/query/Token.java | 61 + .../com/impetus/client/query/TokenClient.java | 57 + .../impetus/client/twitter/TwibaseTest.java | 96 + .../client/twitter/TwitterTestBaseHbase.java | 479 ++++ .../client/twitter/dao/SuperDaoHbase.java | 43 + .../client/twitter/dao/TwitterHbase.java | 156 ++ .../twitter/dao/TwitterServiceHbase.java | 224 ++ .../twitter/entities/ExternalLinkHBase.java | 105 + .../twitter/entities/PersonalDetailHbase.java | 125 + .../twitter/entities/PreferenceHBase.java | 105 + .../client/twitter/entities/TweetHbase.java | 120 + .../client/twitter/entities/UserHBase.java | 227 ++ .../twitter/utils/ExampleUtilsHbase.java | 38 + .../test/resources/META-INF/persistence.xml | 139 ++ .../resources/META-INF/persistence_2_0.xsd | 354 +++ .../test/resources/kundera-hbase.properties | 3 + .../src/test/resources/log4j.properties | 15 + src/kundera-mongo/pom.xml | 99 + .../src/main/java/META-INF/MANIFEST.MF | 3 + .../client/mongodb/DocumentObjectMapper.java | 323 +++ .../impetus/client/mongodb/MongoDBClient.java | 833 +++++++ .../client/mongodb/MongoDBClientFactory.java | 387 ++++ .../mongodb/MongoDBClientProperties.java | 74 + .../client/mongodb/MongoDBConstants.java | 72 + .../client/mongodb/MongoDBDataHandler.java | 471 ++++ .../client/mongodb/MongoEntityReader.java | 62 + .../mongodb/config/MongoDBPropertyReader.java | 214 ++ .../client/mongodb/index/IndexType.java | 41 + .../client/mongodb/query/MongoDBQuery.java | 493 ++++ .../mongodb/query/gis/CircleQueryImpl.java | 61 + .../mongodb/query/gis/EnvelopeQueryImpl.java | 55 + .../query/gis/GeospatialQueryFactory.java | 69 + .../mongodb/query/gis/NearQueryImpl.java | 79 + .../mongodb/query/gis/PolygonQueryImpl.java | 55 + .../mongodb/query/gis/TriangleQueryImpl.java | 54 + .../schemamanager/MongoDBSchemaManager.java | 327 +++ .../client/mongodb/utils/MongoDBUtils.java | 109 + .../java/com/impetus/client/crud/AppUser.java | 105 + .../com/impetus/client/crud/BaseTest.java | 296 +++ .../client/crud/CappedCollectionTest.java | 184 ++ .../com/impetus/client/crud/CollecteTest.java | 112 + .../java/com/impetus/client/crud/Day.java | 6 + .../client/crud/EmbeddableUserTest.java | 107 + .../client/crud/MongoAuthenticationTest.java | 145 ++ .../client/crud/MongoBatchProcessorTest.java | 145 ++ .../client/crud/MongoDBCappedEntity.java | 97 + .../client/crud/MongoDBQueryOnIdTest.java | 466 ++++ .../client/crud/PersonBatchMongoEntity.java | 127 ++ .../com/impetus/client/crud/PersonMongo.java | 142 ++ .../impetus/client/crud/PersonMongoTest.java | 295 +++ .../impetus/client/crud/PhoneDirectory.java | 73 + .../com/impetus/client/crud/UserRoleTest.java | 144 ++ .../compositeType/MongoCompositeTypeTest.java | 368 +++ .../crud/compositeType/MongoCompoundKey.java | 81 + .../crud/compositeType/MongoPrimeUser.java | 94 + .../compositeType/association/UserInfo.java | 145 ++ .../association/UserInfoTest.java | 316 +++ .../client/crud/datatypes/MongoBase.java | 100 + .../crud/datatypes/StudentEntityDef.java | 264 +++ .../client/crud/datatypes/StudentMongo.java | 478 ++++ .../crud/datatypes/StudentMongoBase.java | 348 +++ .../datatypes/StudentMongoBigDecimalTest.java | 565 +++++ .../datatypes/StudentMongoBigIntegerTest.java | 578 +++++ .../StudentMongoBooleanPrimitiveTest.java | 550 +++++ .../StudentMongoBooleanWrapperTest.java | 550 +++++ .../StudentMongoBytePrimitiveTest.java | 575 +++++ .../StudentMongoByteWrapperTest.java | 576 +++++ .../datatypes/StudentMongoCalendarTest.java | 494 ++++ .../crud/datatypes/StudentMongoCharTest.java | 575 +++++ .../datatypes/StudentMongoCharacterTest.java | 576 +++++ .../crud/datatypes/StudentMongoDateTest.java | 577 +++++ .../StudentMongoDoublePrimitiveTest.java | 576 +++++ .../StudentMongoDoubleWrapperTest.java | 572 +++++ .../StudentMongoFloatPrimitiveTest.java | 576 +++++ .../StudentMongoFloatWrapperTest.java | 576 +++++ .../crud/datatypes/StudentMongoIntTest.java | 589 +++++ .../datatypes/StudentMongoIntegerTest.java | 574 +++++ .../StudentMongoLongPrimitiveTest.java | 573 +++++ .../StudentMongoLongWrapperTest.java | 576 +++++ .../StudentMongoShortPrimitiveTest.java | 576 +++++ .../StudentMongoShortWrapperTest.java | 576 +++++ .../datatypes/StudentMongoSqlDateTest.java | 581 +++++ .../datatypes/StudentMongoStringTest.java | 567 +++++ .../crud/datatypes/StudentMongoTest.java | 665 ++++++ .../crud/datatypes/StudentMongoTimeTest.java | 578 +++++ .../datatypes/StudentMongoTimestampTest.java | 582 +++++ .../crud/datatypes/StudentMongoUUIDTest.java | 558 +++++ .../crud/datatypes/entities/Collecte.java | 118 + .../crud/datatypes/entities/Photoo.java | 64 + .../entities/StudentMongoBigDecimal.java | 75 + .../entities/StudentMongoBigInteger.java | 75 + .../StudentMongoBooleanPrimitive.java | 72 + .../entities/StudentMongoBooleanWrapper.java | 72 + .../entities/StudentMongoBytePrimitive.java | 73 + .../entities/StudentMongoByteWrapper.java | 73 + .../entities/StudentMongoCalendar.java | 75 + .../datatypes/entities/StudentMongoChar.java | 73 + .../entities/StudentMongoCharacter.java | 72 + .../datatypes/entities/StudentMongoDate.java | 75 + .../entities/StudentMongoDoublePrimitive.java | 73 + .../entities/StudentMongoDoubleWrapper.java | 73 + .../entities/StudentMongoFloatPrimitive.java | 72 + .../entities/StudentMongoFloatWrapper.java | 73 + .../datatypes/entities/StudentMongoInt.java | 73 + .../entities/StudentMongoInteger.java | 72 + .../entities/StudentMongoLongPrimitive.java | 73 + .../entities/StudentMongoLongWrapper.java | 73 + .../entities/StudentMongoShortPrimitive.java | 73 + .../entities/StudentMongoShortWrapper.java | 73 + .../entities/StudentMongoSqlDate.java | 75 + .../entities/StudentMongoString.java | 73 + .../datatypes/entities/StudentMongoTime.java | 75 + .../entities/StudentMongoTimestamp.java | 75 + .../datatypes/entities/StudentMongoUUID.java | 75 + .../generatedId/MongoGeneratedIdTest.java | 213 ++ .../entites/MongoGeneratedIdDefault.java | 53 + .../entites/MongoGeneratedIdStrategyAuto.java | 59 + .../MongoGeneratedIdStrategyIdentity.java | 56 + .../MongoGeneratedIdStrategySequence.java | 57 + .../MongoGeneratedIdStrategyTable.java | 59 + ...goGeneratedIdWithOutSequenceGenerator.java | 56 + ...MongoGeneratedIdWithOutTableGenerator.java | 56 + ...MongoGeneratedIdWithSequenceGenerator.java | 56 + .../MongoGeneratedIdWithTableGenerator.java | 57 + .../com/impetus/client/gis/MongoGISTest.java | 399 ++++ .../java/com/impetus/client/gis/Person.java | 120 + .../com/impetus/client/gis/PersonGISDao.java | 233 ++ .../java/com/impetus/client/gis/Vehicle.java | 74 + .../config/MongoDBPropertyReaderTest.java | 206 ++ .../client/mongodb/config/MongoUser.java | 80 + .../client/mongodb/config/MongoUserTest.java | 75 + .../config/OperationLevelPropertiesTest.java | 120 + .../client/mongodb/index/IndexTypeTest.java | 58 + .../schemamanager/MongoDBEntitySimple.java | 142 ++ .../MongoDBSchemaManagerTest.java | 268 +++ .../impetus/client/twitter/TwingoTest.java | 99 + .../client/twitter/TwitterTestBaseMongo.java | 489 ++++ .../impetus/client/twitter/dao/SuperDao.java | 43 + .../impetus/client/twitter/dao/Twitter.java | 156 ++ .../client/twitter/dao/TwitterService.java | 228 ++ .../twitter/entities/ExternalLinkMongo.java | 105 + .../twitter/entities/PersonalDetailMongo.java | 125 + .../twitter/entities/PreferenceMongo.java | 105 + .../client/twitter/entities/RoleMongo.java | 88 + .../client/twitter/entities/TweetMongo.java | 120 + .../impetus/client/twitter/entities/User.java | 148 ++ .../client/twitter/entities/UserMongo.java | 227 ++ .../twitter/utils/ExampleUtilsMongo.java | 38 + .../com/impetus/client/utils/MongoUtils.java | 89 + .../test/resources/META-INF/persistence.xml | 120 + .../resources/META-INF/persistence_2_0.xsd | 354 +++ .../test/resources/kundera-mongo.properties | 3 + .../src/test/resources/kunderaMongoTest.xml | 29 + .../src/test/resources/log4j.properties | 15 + src/kundera-neo4j/pom.xml | 118 + .../client/neo4j/GraphEntityMapper.java | 737 ++++++ .../com/impetus/client/neo4j/Neo4JClient.java | 810 +++++++ .../impetus/client/neo4j/Neo4JClientBase.java | 100 + .../client/neo4j/Neo4JClientFactory.java | 201 ++ .../client/neo4j/Neo4JEntityReader.java | 46 + .../client/neo4j/Neo4JTransaction.java | 177 ++ .../neo4j/config/Neo4JPropertyReader.java | 119 + .../client/neo4j/index/Neo4JIndexManager.java | 301 +++ .../client/neo4j/query/Neo4JLuceneQuery.java | 41 + .../client/neo4j/query/Neo4JNativeQuery.java | 33 + .../neo4j/query/Neo4JNativeQueryFactory.java | 48 + .../client/neo4j/query/Neo4JQuery.java | 215 ++ .../client/neo4j/query/Neo4JQueryType.java | 27 + .../client/neo4j/GraphEntityMapperTest.java | 314 +++ .../client/neo4j/Neo4JClientFactoryTest.java | 135 ++ .../impetus/client/neo4j/Neo4JClientTest.java | 319 +++ .../com/impetus/client/neo4j/imdb/Actor.java | 129 ++ .../neo4j/imdb/IMDBBatchInsertionTest.java | 152 ++ .../client/neo4j/imdb/IMDBCRUDTest.java | 136 ++ .../client/neo4j/imdb/IMDBJPAQueriesTest.java | 258 +++ .../neo4j/imdb/IMDBMapMetamodelTest.java | 81 + .../neo4j/imdb/IMDBNativeLuceneQueryTest.java | 204 ++ .../client/neo4j/imdb/IMDBTestBase.java | 204 ++ .../neo4j/imdb/IMDBTransactionTest.java | 212 ++ .../com/impetus/client/neo4j/imdb/Movie.java | 141 ++ .../com/impetus/client/neo4j/imdb/Role.java | 149 ++ .../neo4j/imdb/composite/ActorComposite.java | 123 + .../client/neo4j/imdb/composite/ActorId.java | 84 + .../imdb/composite/IMDBCompositeKeyTest.java | 229 ++ .../neo4j/imdb/composite/MovieComposite.java | 140 ++ .../client/neo4j/imdb/composite/MovieId.java | 84 + .../neo4j/imdb/composite/RoleComposite.java | 148 ++ .../client/neo4j/imdb/composite/RoleId.java | 104 + .../neo4j/imdb/datatype/ActorAllDataType.java | 475 ++++ .../imdb/datatype/IMDBAllDataTypeTest.java | 290 +++ .../neo4j/imdb/datatype/MovieAllDataType.java | 141 ++ .../neo4j/imdb/datatype/RoleAllDataType.java | 502 ++++ .../test/resources/META-INF/persistence.xml | 59 + .../src/test/resources/kunderaNeo4JTest.xml | 73 + src/kundera-oracle-nosql/PROFILE_PICTURE | Bin 0 -> 1852277 bytes src/kundera-oracle-nosql/lucene/_0.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_0.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_0.fnm | 2 + src/kundera-oracle-nosql/lucene/_0.frq | 1 + src/kundera-oracle-nosql/lucene/_0.nrm | 1 + src/kundera-oracle-nosql/lucene/_0.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_0.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_0.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_11.fdt | Bin 0 -> 862 bytes src/kundera-oracle-nosql/lucene/_11.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_11.fnm | 2 + src/kundera-oracle-nosql/lucene/_11.frq | 1 + src/kundera-oracle-nosql/lucene/_11.nrm | 1 + src/kundera-oracle-nosql/lucene/_11.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_11.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_11.tis | Bin 0 -> 347 bytes src/kundera-oracle-nosql/lucene/_13.fdt | Bin 0 -> 864 bytes src/kundera-oracle-nosql/lucene/_13.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_13.fnm | 2 + src/kundera-oracle-nosql/lucene/_13.frq | 1 + src/kundera-oracle-nosql/lucene/_13.nrm | 1 + src/kundera-oracle-nosql/lucene/_13.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_13.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_13.tis | Bin 0 -> 349 bytes src/kundera-oracle-nosql/lucene/_15.fdt | Bin 0 -> 866 bytes src/kundera-oracle-nosql/lucene/_15.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_15.fnm | 2 + src/kundera-oracle-nosql/lucene/_15.frq | 1 + src/kundera-oracle-nosql/lucene/_15.nrm | 1 + src/kundera-oracle-nosql/lucene/_15.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_15.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_15.tis | Bin 0 -> 351 bytes src/kundera-oracle-nosql/lucene/_17.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_17.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_17.fnm | 2 + src/kundera-oracle-nosql/lucene/_17.frq | 1 + src/kundera-oracle-nosql/lucene/_17.nrm | 1 + src/kundera-oracle-nosql/lucene/_17.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_17.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_17.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_19.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_19.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_19.fnm | 2 + src/kundera-oracle-nosql/lucene/_19.frq | 1 + src/kundera-oracle-nosql/lucene/_19.nrm | 1 + src/kundera-oracle-nosql/lucene/_19.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_19.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_19.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_1b.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_1b.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_1b.fnm | 2 + src/kundera-oracle-nosql/lucene/_1b.frq | 1 + src/kundera-oracle-nosql/lucene/_1b.nrm | 1 + src/kundera-oracle-nosql/lucene/_1b.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_1b.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1b.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_1d.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_1d.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_1d.fnm | 2 + src/kundera-oracle-nosql/lucene/_1d.frq | 1 + src/kundera-oracle-nosql/lucene/_1d.nrm | 1 + src/kundera-oracle-nosql/lucene/_1d.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_1d.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1d.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_1e.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_1e.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_1e.fnm | 2 + src/kundera-oracle-nosql/lucene/_1e.frq | 1 + src/kundera-oracle-nosql/lucene/_1e.nrm | 1 + src/kundera-oracle-nosql/lucene/_1e.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_1e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1e.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_1g.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_1g.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_1g.fnm | 2 + src/kundera-oracle-nosql/lucene/_1g.frq | 1 + src/kundera-oracle-nosql/lucene/_1g.nrm | 1 + src/kundera-oracle-nosql/lucene/_1g.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_1g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1g.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_1i.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_1i.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_1i.fnm | 2 + src/kundera-oracle-nosql/lucene/_1i.frq | 1 + src/kundera-oracle-nosql/lucene/_1i.nrm | 1 + src/kundera-oracle-nosql/lucene/_1i.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_1i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1i.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_1k.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_1k.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_1k.fnm | 2 + src/kundera-oracle-nosql/lucene/_1k.frq | 1 + src/kundera-oracle-nosql/lucene/_1k.nrm | 1 + src/kundera-oracle-nosql/lucene/_1k.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_1k.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1k.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_1m.fdt | Bin 0 -> 862 bytes src/kundera-oracle-nosql/lucene/_1m.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_1m.fnm | 2 + src/kundera-oracle-nosql/lucene/_1m.frq | 1 + src/kundera-oracle-nosql/lucene/_1m.nrm | 1 + src/kundera-oracle-nosql/lucene/_1m.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_1m.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1m.tis | Bin 0 -> 347 bytes src/kundera-oracle-nosql/lucene/_1o.fdt | Bin 0 -> 864 bytes src/kundera-oracle-nosql/lucene/_1o.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_1o.fnm | 2 + src/kundera-oracle-nosql/lucene/_1o.frq | 1 + src/kundera-oracle-nosql/lucene/_1o.nrm | 1 + src/kundera-oracle-nosql/lucene/_1o.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_1o.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1o.tis | Bin 0 -> 349 bytes src/kundera-oracle-nosql/lucene/_1q.fdt | Bin 0 -> 866 bytes src/kundera-oracle-nosql/lucene/_1q.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_1q.fnm | 2 + src/kundera-oracle-nosql/lucene/_1q.frq | 1 + src/kundera-oracle-nosql/lucene/_1q.nrm | 1 + src/kundera-oracle-nosql/lucene/_1q.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_1q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1q.tis | Bin 0 -> 351 bytes src/kundera-oracle-nosql/lucene/_1s.fdt | Bin 0 -> 272 bytes src/kundera-oracle-nosql/lucene/_1s.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_1s.fnm | 1 + src/kundera-oracle-nosql/lucene/_1s.frq | 1 + src/kundera-oracle-nosql/lucene/_1s.nrm | 1 + src/kundera-oracle-nosql/lucene/_1s.prx | Bin 0 -> 8 bytes src/kundera-oracle-nosql/lucene/_1s.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1s.tis | Bin 0 -> 257 bytes src/kundera-oracle-nosql/lucene/_1u.fdt | Bin 0 -> 279 bytes src/kundera-oracle-nosql/lucene/_1u.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_1u.fnm | 1 + src/kundera-oracle-nosql/lucene/_1u.frq | 1 + src/kundera-oracle-nosql/lucene/_1u.nrm | 1 + src/kundera-oracle-nosql/lucene/_1u.prx | Bin 0 -> 14 bytes src/kundera-oracle-nosql/lucene/_1u.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1u.tis | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_1w.fdt | Bin 0 -> 554 bytes src/kundera-oracle-nosql/lucene/_1w.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_1w.fnm | 1 + src/kundera-oracle-nosql/lucene/_1w.frq | 1 + src/kundera-oracle-nosql/lucene/_1w.nrm | 1 + src/kundera-oracle-nosql/lucene/_1w.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_1w.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1w.tis | Bin 0 -> 346 bytes src/kundera-oracle-nosql/lucene/_1y.fdt | Bin 0 -> 829 bytes src/kundera-oracle-nosql/lucene/_1y.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_1y.fnm | 1 + src/kundera-oracle-nosql/lucene/_1y.frq | 1 + src/kundera-oracle-nosql/lucene/_1y.nrm | 1 + src/kundera-oracle-nosql/lucene/_1y.prx | Bin 0 -> 42 bytes src/kundera-oracle-nosql/lucene/_1y.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_1y.tis | Bin 0 -> 410 bytes src/kundera-oracle-nosql/lucene/_2.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_2.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2.fnm | 2 + src/kundera-oracle-nosql/lucene/_2.frq | 1 + src/kundera-oracle-nosql/lucene/_2.nrm | 1 + src/kundera-oracle-nosql/lucene/_2.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_20.fdt | Bin 0 -> 1104 bytes src/kundera-oracle-nosql/lucene/_20.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_20.fnm | 1 + src/kundera-oracle-nosql/lucene/_20.frq | 1 + src/kundera-oracle-nosql/lucene/_20.nrm | 1 + src/kundera-oracle-nosql/lucene/_20.prx | Bin 0 -> 56 bytes src/kundera-oracle-nosql/lucene/_20.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_20.tis | Bin 0 -> 474 bytes src/kundera-oracle-nosql/lucene/_22.fdt | Bin 0 -> 1107 bytes src/kundera-oracle-nosql/lucene/_22.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_22.fnm | 1 + src/kundera-oracle-nosql/lucene/_22.frq | 1 + src/kundera-oracle-nosql/lucene/_22.nrm | 1 + src/kundera-oracle-nosql/lucene/_22.prx | Bin 0 -> 56 bytes src/kundera-oracle-nosql/lucene/_22.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_22.tis | Bin 0 -> 477 bytes src/kundera-oracle-nosql/lucene/_24.fdt | Bin 0 -> 1110 bytes src/kundera-oracle-nosql/lucene/_24.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_24.fnm | 1 + src/kundera-oracle-nosql/lucene/_24.frq | 1 + src/kundera-oracle-nosql/lucene/_24.nrm | 1 + src/kundera-oracle-nosql/lucene/_24.prx | Bin 0 -> 56 bytes src/kundera-oracle-nosql/lucene/_24.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_24.tis | Bin 0 -> 480 bytes src/kundera-oracle-nosql/lucene/_26.fdt | Bin 0 -> 1113 bytes src/kundera-oracle-nosql/lucene/_26.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_26.fnm | 1 + src/kundera-oracle-nosql/lucene/_26.frq | 1 + src/kundera-oracle-nosql/lucene/_26.nrm | 1 + src/kundera-oracle-nosql/lucene/_26.prx | Bin 0 -> 56 bytes src/kundera-oracle-nosql/lucene/_26.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_26.tis | Bin 0 -> 483 bytes src/kundera-oracle-nosql/lucene/_28.fdt | Bin 0 -> 279 bytes src/kundera-oracle-nosql/lucene/_28.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_28.fnm | 1 + src/kundera-oracle-nosql/lucene/_28.frq | 1 + src/kundera-oracle-nosql/lucene/_28.nrm | 1 + src/kundera-oracle-nosql/lucene/_28.prx | Bin 0 -> 14 bytes src/kundera-oracle-nosql/lucene/_28.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_28.tis | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_2a.fdt | Bin 0 -> 554 bytes src/kundera-oracle-nosql/lucene/_2a.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2a.fnm | 1 + src/kundera-oracle-nosql/lucene/_2a.frq | 1 + src/kundera-oracle-nosql/lucene/_2a.nrm | 1 + src/kundera-oracle-nosql/lucene/_2a.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_2a.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2a.tis | Bin 0 -> 346 bytes src/kundera-oracle-nosql/lucene/_2c.fdt | Bin 0 -> 829 bytes src/kundera-oracle-nosql/lucene/_2c.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_2c.fnm | 1 + src/kundera-oracle-nosql/lucene/_2c.frq | 1 + src/kundera-oracle-nosql/lucene/_2c.nrm | 1 + src/kundera-oracle-nosql/lucene/_2c.prx | Bin 0 -> 42 bytes src/kundera-oracle-nosql/lucene/_2c.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2c.tis | Bin 0 -> 410 bytes src/kundera-oracle-nosql/lucene/_2e.fdt | Bin 0 -> 1104 bytes src/kundera-oracle-nosql/lucene/_2e.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_2e.fnm | 1 + src/kundera-oracle-nosql/lucene/_2e.frq | 1 + src/kundera-oracle-nosql/lucene/_2e.nrm | 1 + src/kundera-oracle-nosql/lucene/_2e.prx | Bin 0 -> 56 bytes src/kundera-oracle-nosql/lucene/_2e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2e.tis | Bin 0 -> 474 bytes src/kundera-oracle-nosql/lucene/_2f.fdt | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_2f.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2f.fnm | 2 + src/kundera-oracle-nosql/lucene/_2f.frq | 1 + src/kundera-oracle-nosql/lucene/_2f.nrm | 1 + src/kundera-oracle-nosql/lucene/_2f.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2f.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2f.tis | Bin 0 -> 216 bytes src/kundera-oracle-nosql/lucene/_2g.fdt | Bin 0 -> 221 bytes src/kundera-oracle-nosql/lucene/_2g.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2g.fnm | 2 + src/kundera-oracle-nosql/lucene/_2g.frq | 1 + src/kundera-oracle-nosql/lucene/_2g.nrm | 1 + src/kundera-oracle-nosql/lucene/_2g.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2g.tis | Bin 0 -> 217 bytes src/kundera-oracle-nosql/lucene/_2h.fdt | Bin 0 -> 225 bytes src/kundera-oracle-nosql/lucene/_2h.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2h.fnm | 2 + src/kundera-oracle-nosql/lucene/_2h.frq | 1 + src/kundera-oracle-nosql/lucene/_2h.nrm | 1 + src/kundera-oracle-nosql/lucene/_2h.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2h.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2h.tis | Bin 0 -> 221 bytes src/kundera-oracle-nosql/lucene/_2i.fdt | Bin 0 -> 221 bytes src/kundera-oracle-nosql/lucene/_2i.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2i.fnm | 2 + src/kundera-oracle-nosql/lucene/_2i.frq | 1 + src/kundera-oracle-nosql/lucene/_2i.nrm | 1 + src/kundera-oracle-nosql/lucene/_2i.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2i.tis | Bin 0 -> 217 bytes src/kundera-oracle-nosql/lucene/_2j.fdt | Bin 0 -> 216 bytes src/kundera-oracle-nosql/lucene/_2j.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2j.fnm | 2 + src/kundera-oracle-nosql/lucene/_2j.frq | 1 + src/kundera-oracle-nosql/lucene/_2j.nrm | 1 + src/kundera-oracle-nosql/lucene/_2j.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2j.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2j.tis | Bin 0 -> 212 bytes src/kundera-oracle-nosql/lucene/_2l.fdt | Bin 0 -> 428 bytes src/kundera-oracle-nosql/lucene/_2l.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2l.fnm | 2 + src/kundera-oracle-nosql/lucene/_2l.frq | 1 + src/kundera-oracle-nosql/lucene/_2l.nrm | 1 + src/kundera-oracle-nosql/lucene/_2l.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2l.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2l.tis | Bin 0 -> 250 bytes src/kundera-oracle-nosql/lucene/_2n.fdt | Bin 0 -> 640 bytes src/kundera-oracle-nosql/lucene/_2n.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_2n.fnm | 2 + src/kundera-oracle-nosql/lucene/_2n.frq | 1 + src/kundera-oracle-nosql/lucene/_2n.nrm | 1 + src/kundera-oracle-nosql/lucene/_2n.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_2n.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2n.tis | Bin 0 -> 285 bytes src/kundera-oracle-nosql/lucene/_2q.fdt | Bin 0 -> 216 bytes src/kundera-oracle-nosql/lucene/_2q.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2q.fnm | 2 + src/kundera-oracle-nosql/lucene/_2q.frq | 1 + src/kundera-oracle-nosql/lucene/_2q.nrm | 1 + src/kundera-oracle-nosql/lucene/_2q.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2q.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_2r.fdt | Bin 0 -> 216 bytes src/kundera-oracle-nosql/lucene/_2r.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2r.fnm | 2 + src/kundera-oracle-nosql/lucene/_2r.frq | 1 + src/kundera-oracle-nosql/lucene/_2r.nrm | 1 + src/kundera-oracle-nosql/lucene/_2r.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_2r.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2r.tis | Bin 0 -> 212 bytes src/kundera-oracle-nosql/lucene/_2t.fdt | Bin 0 -> 428 bytes src/kundera-oracle-nosql/lucene/_2t.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2t.fnm | 2 + src/kundera-oracle-nosql/lucene/_2t.frq | 1 + src/kundera-oracle-nosql/lucene/_2t.nrm | 1 + src/kundera-oracle-nosql/lucene/_2t.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_2t.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2t.tis | Bin 0 -> 250 bytes src/kundera-oracle-nosql/lucene/_2v.fdt | Bin 0 -> 640 bytes src/kundera-oracle-nosql/lucene/_2v.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_2v.fnm | 2 + src/kundera-oracle-nosql/lucene/_2v.frq | 1 + src/kundera-oracle-nosql/lucene/_2v.nrm | 1 + src/kundera-oracle-nosql/lucene/_2v.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_2v.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2v.tis | Bin 0 -> 285 bytes src/kundera-oracle-nosql/lucene/_2x.fdt | Bin 0 -> 640 bytes src/kundera-oracle-nosql/lucene/_2x.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_2x.fnm | 2 + src/kundera-oracle-nosql/lucene/_2x.frq | 1 + src/kundera-oracle-nosql/lucene/_2x.nrm | 1 + src/kundera-oracle-nosql/lucene/_2x.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_2x.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2x.tis | Bin 0 -> 285 bytes src/kundera-oracle-nosql/lucene/_2z.fdt | Bin 0 -> 177 bytes src/kundera-oracle-nosql/lucene/_2z.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_2z.fnm | 1 + src/kundera-oracle-nosql/lucene/_2z.frq | 1 + src/kundera-oracle-nosql/lucene/_2z.nrm | 1 + src/kundera-oracle-nosql/lucene/_2z.prx | Bin 0 -> 8 bytes src/kundera-oracle-nosql/lucene/_2z.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_2z.tis | Bin 0 -> 231 bytes src/kundera-oracle-nosql/lucene/_31.fdt | Bin 0 -> 412 bytes src/kundera-oracle-nosql/lucene/_31.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_31.fnm | 1 + src/kundera-oracle-nosql/lucene/_31.frq | 1 + src/kundera-oracle-nosql/lucene/_31.nrm | 1 + src/kundera-oracle-nosql/lucene/_31.prx | Bin 0 -> 18 bytes src/kundera-oracle-nosql/lucene/_31.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_31.tis | Bin 0 -> 360 bytes src/kundera-oracle-nosql/lucene/_33.fdt | Bin 0 -> 585 bytes src/kundera-oracle-nosql/lucene/_33.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_33.fnm | 1 + src/kundera-oracle-nosql/lucene/_33.frq | 1 + src/kundera-oracle-nosql/lucene/_33.nrm | 1 + src/kundera-oracle-nosql/lucene/_33.prx | Bin 0 -> 26 bytes src/kundera-oracle-nosql/lucene/_33.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_33.tis | Bin 0 -> 395 bytes src/kundera-oracle-nosql/lucene/_35.fdt | Bin 0 -> 820 bytes src/kundera-oracle-nosql/lucene/_35.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_35.fnm | 1 + src/kundera-oracle-nosql/lucene/_35.frq | 1 + src/kundera-oracle-nosql/lucene/_35.nrm | 1 + src/kundera-oracle-nosql/lucene/_35.prx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_35.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_35.tis | Bin 0 -> 438 bytes src/kundera-oracle-nosql/lucene/_37.fdt | Bin 0 -> 993 bytes src/kundera-oracle-nosql/lucene/_37.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_37.fnm | 1 + src/kundera-oracle-nosql/lucene/_37.frq | 1 + src/kundera-oracle-nosql/lucene/_37.nrm | 1 + src/kundera-oracle-nosql/lucene/_37.prx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_37.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_37.tis | Bin 0 -> 472 bytes src/kundera-oracle-nosql/lucene/_39.fdt | Bin 0 -> 1228 bytes src/kundera-oracle-nosql/lucene/_39.fdx | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_39.fnm | 1 + src/kundera-oracle-nosql/lucene/_39.frq | 1 + src/kundera-oracle-nosql/lucene/_39.nrm | 1 + src/kundera-oracle-nosql/lucene/_39.prx | Bin 0 -> 54 bytes src/kundera-oracle-nosql/lucene/_39.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_39.tis | Bin 0 -> 513 bytes src/kundera-oracle-nosql/lucene/_3b.fdt | Bin 0 -> 1401 bytes src/kundera-oracle-nosql/lucene/_3b.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_3b.fnm | 1 + src/kundera-oracle-nosql/lucene/_3b.frq | 1 + src/kundera-oracle-nosql/lucene/_3b.nrm | 1 + src/kundera-oracle-nosql/lucene/_3b.prx | Bin 0 -> 62 bytes src/kundera-oracle-nosql/lucene/_3b.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3b.tis | Bin 0 -> 547 bytes src/kundera-oracle-nosql/lucene/_3d.fdt | Bin 0 -> 1636 bytes src/kundera-oracle-nosql/lucene/_3d.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3d.fnm | 1 + src/kundera-oracle-nosql/lucene/_3d.frq | 1 + src/kundera-oracle-nosql/lucene/_3d.nrm | 1 + src/kundera-oracle-nosql/lucene/_3d.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3d.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3d.tis | Bin 0 -> 588 bytes src/kundera-oracle-nosql/lucene/_3f.fdt | Bin 0 -> 1637 bytes src/kundera-oracle-nosql/lucene/_3f.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3f.fnm | 1 + src/kundera-oracle-nosql/lucene/_3f.frq | 1 + src/kundera-oracle-nosql/lucene/_3f.nrm | 1 + src/kundera-oracle-nosql/lucene/_3f.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3f.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3f.tis | Bin 0 -> 589 bytes src/kundera-oracle-nosql/lucene/_3h.fdt | Bin 0 -> 1639 bytes src/kundera-oracle-nosql/lucene/_3h.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3h.fnm | 1 + src/kundera-oracle-nosql/lucene/_3h.frq | 1 + src/kundera-oracle-nosql/lucene/_3h.nrm | 1 + src/kundera-oracle-nosql/lucene/_3h.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3h.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3h.tis | Bin 0 -> 591 bytes src/kundera-oracle-nosql/lucene/_3j.fdt | Bin 0 -> 1640 bytes src/kundera-oracle-nosql/lucene/_3j.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3j.fnm | 1 + src/kundera-oracle-nosql/lucene/_3j.frq | 1 + src/kundera-oracle-nosql/lucene/_3j.nrm | 1 + src/kundera-oracle-nosql/lucene/_3j.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3j.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3j.tis | Bin 0 -> 592 bytes src/kundera-oracle-nosql/lucene/_3l.fdt | Bin 0 -> 1642 bytes src/kundera-oracle-nosql/lucene/_3l.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3l.fnm | 1 + src/kundera-oracle-nosql/lucene/_3l.frq | 1 + src/kundera-oracle-nosql/lucene/_3l.nrm | 1 + src/kundera-oracle-nosql/lucene/_3l.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3l.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3l.tis | Bin 0 -> 594 bytes src/kundera-oracle-nosql/lucene/_3n.fdt | Bin 0 -> 1643 bytes src/kundera-oracle-nosql/lucene/_3n.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3n.fnm | 1 + src/kundera-oracle-nosql/lucene/_3n.frq | 1 + src/kundera-oracle-nosql/lucene/_3n.nrm | 1 + src/kundera-oracle-nosql/lucene/_3n.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3n.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3n.tis | Bin 0 -> 595 bytes src/kundera-oracle-nosql/lucene/_3p.fdt | Bin 0 -> 1645 bytes src/kundera-oracle-nosql/lucene/_3p.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3p.fnm | 1 + src/kundera-oracle-nosql/lucene/_3p.frq | 1 + src/kundera-oracle-nosql/lucene/_3p.nrm | 1 + src/kundera-oracle-nosql/lucene/_3p.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3p.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3p.tis | Bin 0 -> 597 bytes src/kundera-oracle-nosql/lucene/_3r.fdt | Bin 0 -> 1646 bytes src/kundera-oracle-nosql/lucene/_3r.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_3r.fnm | 1 + src/kundera-oracle-nosql/lucene/_3r.frq | 1 + src/kundera-oracle-nosql/lucene/_3r.nrm | 1 + src/kundera-oracle-nosql/lucene/_3r.prx | Bin 0 -> 72 bytes src/kundera-oracle-nosql/lucene/_3r.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3r.tis | Bin 0 -> 598 bytes src/kundera-oracle-nosql/lucene/_3t.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_3t.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_3t.fnm | 2 + src/kundera-oracle-nosql/lucene/_3t.frq | 1 + src/kundera-oracle-nosql/lucene/_3t.nrm | 1 + src/kundera-oracle-nosql/lucene/_3t.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_3t.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3t.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_3v.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_3v.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_3v.fnm | 2 + src/kundera-oracle-nosql/lucene/_3v.frq | 1 + src/kundera-oracle-nosql/lucene/_3v.nrm | 1 + src/kundera-oracle-nosql/lucene/_3v.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_3v.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3v.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_3x.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_3x.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_3x.fnm | 2 + src/kundera-oracle-nosql/lucene/_3x.frq | 1 + src/kundera-oracle-nosql/lucene/_3x.nrm | 1 + src/kundera-oracle-nosql/lucene/_3x.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_3x.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3x.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_3z.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_3z.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_3z.fnm | 2 + src/kundera-oracle-nosql/lucene/_3z.frq | 1 + src/kundera-oracle-nosql/lucene/_3z.nrm | 1 + src/kundera-oracle-nosql/lucene/_3z.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_3z.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_3z.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_4.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_4.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4.fnm | 2 + src/kundera-oracle-nosql/lucene/_4.frq | 1 + src/kundera-oracle-nosql/lucene/_4.nrm | 1 + src/kundera-oracle-nosql/lucene/_4.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_4.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_41.fdt | Bin 0 -> 862 bytes src/kundera-oracle-nosql/lucene/_41.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_41.fnm | 2 + src/kundera-oracle-nosql/lucene/_41.frq | 1 + src/kundera-oracle-nosql/lucene/_41.nrm | 1 + src/kundera-oracle-nosql/lucene/_41.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_41.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_41.tis | Bin 0 -> 347 bytes src/kundera-oracle-nosql/lucene/_43.fdt | Bin 0 -> 864 bytes src/kundera-oracle-nosql/lucene/_43.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_43.fnm | 2 + src/kundera-oracle-nosql/lucene/_43.frq | 1 + src/kundera-oracle-nosql/lucene/_43.nrm | 1 + src/kundera-oracle-nosql/lucene/_43.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_43.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_43.tis | Bin 0 -> 349 bytes src/kundera-oracle-nosql/lucene/_45.fdt | Bin 0 -> 866 bytes src/kundera-oracle-nosql/lucene/_45.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_45.fnm | 2 + src/kundera-oracle-nosql/lucene/_45.frq | 1 + src/kundera-oracle-nosql/lucene/_45.nrm | 1 + src/kundera-oracle-nosql/lucene/_45.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_45.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_45.tis | Bin 0 -> 351 bytes src/kundera-oracle-nosql/lucene/_47.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_47.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_47.fnm | 2 + src/kundera-oracle-nosql/lucene/_47.frq | 1 + src/kundera-oracle-nosql/lucene/_47.nrm | 1 + src/kundera-oracle-nosql/lucene/_47.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_47.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_47.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_49.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_49.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_49.fnm | 2 + src/kundera-oracle-nosql/lucene/_49.frq | 1 + src/kundera-oracle-nosql/lucene/_49.nrm | 1 + src/kundera-oracle-nosql/lucene/_49.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_49.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_49.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_4b.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_4b.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4b.fnm | 2 + src/kundera-oracle-nosql/lucene/_4b.frq | 1 + src/kundera-oracle-nosql/lucene/_4b.nrm | 1 + src/kundera-oracle-nosql/lucene/_4b.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_4b.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4b.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_4d.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_4d.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_4d.fnm | 2 + src/kundera-oracle-nosql/lucene/_4d.frq | 1 + src/kundera-oracle-nosql/lucene/_4d.nrm | 1 + src/kundera-oracle-nosql/lucene/_4d.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_4d.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4d.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_4e.fdt | Bin 0 -> 334 bytes src/kundera-oracle-nosql/lucene/_4e.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_4e.fnm | 1 + src/kundera-oracle-nosql/lucene/_4e.frq | 1 + src/kundera-oracle-nosql/lucene/_4e.nrm | 1 + src/kundera-oracle-nosql/lucene/_4e.prx | Bin 0 -> 8 bytes src/kundera-oracle-nosql/lucene/_4e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4e.tis | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_4g.fdt | Bin 0 -> 644 bytes src/kundera-oracle-nosql/lucene/_4g.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4g.fnm | 1 + src/kundera-oracle-nosql/lucene/_4g.frq | 1 + src/kundera-oracle-nosql/lucene/_4g.nrm | 1 + src/kundera-oracle-nosql/lucene/_4g.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4g.tis | Bin 0 -> 388 bytes src/kundera-oracle-nosql/lucene/_4i.fdt | Bin 0 -> 950 bytes src/kundera-oracle-nosql/lucene/_4i.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4i.fnm | 1 + src/kundera-oracle-nosql/lucene/_4i.frq | 1 + src/kundera-oracle-nosql/lucene/_4i.nrm | 1 + src/kundera-oracle-nosql/lucene/_4i.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4i.tis | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_4i_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_4k.fdt | Bin 0 -> 620 bytes src/kundera-oracle-nosql/lucene/_4k.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4k.fnm | 1 + src/kundera-oracle-nosql/lucene/_4k.frq | 1 + src/kundera-oracle-nosql/lucene/_4k.nrm | 1 + src/kundera-oracle-nosql/lucene/_4k.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4k.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4k.tis | Bin 0 -> 360 bytes src/kundera-oracle-nosql/lucene/_4m.fdt | Bin 0 -> 950 bytes src/kundera-oracle-nosql/lucene/_4m.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4m.fnm | 1 + src/kundera-oracle-nosql/lucene/_4m.frq | 1 + src/kundera-oracle-nosql/lucene/_4m.nrm | 1 + src/kundera-oracle-nosql/lucene/_4m.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4m.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4m.tis | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_4o.fdt | Bin 0 -> 950 bytes src/kundera-oracle-nosql/lucene/_4o.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4o.fnm | 1 + src/kundera-oracle-nosql/lucene/_4o.frq | 1 + src/kundera-oracle-nosql/lucene/_4o.nrm | 1 + src/kundera-oracle-nosql/lucene/_4o.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4o.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4o.tis | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_4q.fdt | Bin 0 -> 950 bytes src/kundera-oracle-nosql/lucene/_4q.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4q.fnm | 1 + src/kundera-oracle-nosql/lucene/_4q.frq | 1 + src/kundera-oracle-nosql/lucene/_4q.nrm | 1 + src/kundera-oracle-nosql/lucene/_4q.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4q.tis | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_4q_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_4s.fdt | Bin 0 -> 620 bytes src/kundera-oracle-nosql/lucene/_4s.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4s.fnm | 1 + src/kundera-oracle-nosql/lucene/_4s.frq | 1 + src/kundera-oracle-nosql/lucene/_4s.nrm | 1 + src/kundera-oracle-nosql/lucene/_4s.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_4s.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4s.tis | Bin 0 -> 360 bytes src/kundera-oracle-nosql/lucene/_4u.fdt | Bin 0 -> 911 bytes src/kundera-oracle-nosql/lucene/_4u.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4u.fnm | 1 + src/kundera-oracle-nosql/lucene/_4u.frq | 1 + src/kundera-oracle-nosql/lucene/_4u.nrm | 1 + src/kundera-oracle-nosql/lucene/_4u.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4u.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4u.tis | Bin 0 -> 479 bytes src/kundera-oracle-nosql/lucene/_4w.fdt | Bin 0 -> 911 bytes src/kundera-oracle-nosql/lucene/_4w.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4w.fnm | 1 + src/kundera-oracle-nosql/lucene/_4w.frq | 1 + src/kundera-oracle-nosql/lucene/_4w.nrm | 1 + src/kundera-oracle-nosql/lucene/_4w.prx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4w.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4w.tis | Bin 0 -> 479 bytes src/kundera-oracle-nosql/lucene/_4y.fdt | Bin 0 -> 1016 bytes src/kundera-oracle-nosql/lucene/_4y.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_4y.fnm | 2 + src/kundera-oracle-nosql/lucene/_4y.frq | 1 + src/kundera-oracle-nosql/lucene/_4y.nrm | 1 + src/kundera-oracle-nosql/lucene/_4y.prx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_4y.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_4y.tis | Bin 0 -> 659 bytes src/kundera-oracle-nosql/lucene/_50.fdt | Bin 0 -> 1412 bytes src/kundera-oracle-nosql/lucene/_50.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_50.fnm | 2 + src/kundera-oracle-nosql/lucene/_50.frq | 1 + src/kundera-oracle-nosql/lucene/_50.nrm | 1 + src/kundera-oracle-nosql/lucene/_50.prx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_50.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_50.tis | Bin 0 -> 895 bytes src/kundera-oracle-nosql/lucene/_52.fdt | Bin 0 -> 1808 bytes src/kundera-oracle-nosql/lucene/_52.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_52.fnm | 2 + src/kundera-oracle-nosql/lucene/_52.frq | 1 + src/kundera-oracle-nosql/lucene/_52.nrm | 1 + src/kundera-oracle-nosql/lucene/_52.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_52.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_52.tis | Bin 0 -> 1199 bytes src/kundera-oracle-nosql/lucene/_52_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_54.fdt | Bin 0 -> 1412 bytes src/kundera-oracle-nosql/lucene/_54.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_54.fnm | 2 + src/kundera-oracle-nosql/lucene/_54.frq | 1 + src/kundera-oracle-nosql/lucene/_54.nrm | 1 + src/kundera-oracle-nosql/lucene/_54.prx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_54.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_54.tis | Bin 0 -> 963 bytes src/kundera-oracle-nosql/lucene/_56.fdt | Bin 0 -> 1808 bytes src/kundera-oracle-nosql/lucene/_56.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_56.fnm | 2 + src/kundera-oracle-nosql/lucene/_56.frq | 1 + src/kundera-oracle-nosql/lucene/_56.nrm | 1 + src/kundera-oracle-nosql/lucene/_56.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_56.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_56.tis | Bin 0 -> 1199 bytes src/kundera-oracle-nosql/lucene/_58.fdt | Bin 0 -> 1808 bytes src/kundera-oracle-nosql/lucene/_58.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_58.fnm | 2 + src/kundera-oracle-nosql/lucene/_58.frq | 1 + src/kundera-oracle-nosql/lucene/_58.nrm | 1 + src/kundera-oracle-nosql/lucene/_58.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_58.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_58.tis | Bin 0 -> 1199 bytes src/kundera-oracle-nosql/lucene/_5a.fdt | Bin 0 -> 1808 bytes src/kundera-oracle-nosql/lucene/_5a.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_5a.fnm | 2 + src/kundera-oracle-nosql/lucene/_5a.frq | 1 + src/kundera-oracle-nosql/lucene/_5a.nrm | 1 + src/kundera-oracle-nosql/lucene/_5a.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5a.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5a.tis | Bin 0 -> 1199 bytes src/kundera-oracle-nosql/lucene/_5a_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_5c.fdt | Bin 0 -> 1412 bytes src/kundera-oracle-nosql/lucene/_5c.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_5c.fnm | 2 + src/kundera-oracle-nosql/lucene/_5c.frq | 1 + src/kundera-oracle-nosql/lucene/_5c.nrm | 1 + src/kundera-oracle-nosql/lucene/_5c.prx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_5c.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5c.tis | Bin 0 -> 963 bytes src/kundera-oracle-nosql/lucene/_5e.fdt | Bin 0 -> 1767 bytes src/kundera-oracle-nosql/lucene/_5e.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_5e.fnm | 1 + src/kundera-oracle-nosql/lucene/_5e.frq | 1 + src/kundera-oracle-nosql/lucene/_5e.nrm | 1 + src/kundera-oracle-nosql/lucene/_5e.prx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_5e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5e.tis | Bin 0 -> 1139 bytes src/kundera-oracle-nosql/lucene/_5g.fdt | Bin 0 -> 1767 bytes src/kundera-oracle-nosql/lucene/_5g.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_5g.fnm | 1 + src/kundera-oracle-nosql/lucene/_5g.frq | 1 + src/kundera-oracle-nosql/lucene/_5g.nrm | 1 + src/kundera-oracle-nosql/lucene/_5g.prx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_5g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5g.tis | Bin 0 -> 1139 bytes src/kundera-oracle-nosql/lucene/_5i.fdt | Bin 0 -> 1690 bytes src/kundera-oracle-nosql/lucene/_5i.fdx | Bin 0 -> 44 bytes src/kundera-oracle-nosql/lucene/_5i.fnm | 1 + src/kundera-oracle-nosql/lucene/_5i.frq | 1 + src/kundera-oracle-nosql/lucene/_5i.nrm | 1 + src/kundera-oracle-nosql/lucene/_5i.prx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_5i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5i.tis | Bin 0 -> 1055 bytes src/kundera-oracle-nosql/lucene/_5k.fdt | Bin 0 -> 1964 bytes src/kundera-oracle-nosql/lucene/_5k.fdx | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_5k.fnm | 1 + src/kundera-oracle-nosql/lucene/_5k.frq | 1 + src/kundera-oracle-nosql/lucene/_5k.nrm | 1 + src/kundera-oracle-nosql/lucene/_5k.prx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_5k.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5k.tis | Bin 0 -> 1080 bytes src/kundera-oracle-nosql/lucene/_5m.fdt | Bin 0 -> 2262 bytes src/kundera-oracle-nosql/lucene/_5m.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_5m.fnm | 1 + src/kundera-oracle-nosql/lucene/_5m.frq | 1 + src/kundera-oracle-nosql/lucene/_5m.nrm | 1 + src/kundera-oracle-nosql/lucene/_5m.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5m.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5m.tis | Bin 0 -> 1125 bytes src/kundera-oracle-nosql/lucene/_5m_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_5o.fdt | Bin 0 -> 1984 bytes src/kundera-oracle-nosql/lucene/_5o.fdx | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_5o.fnm | 1 + src/kundera-oracle-nosql/lucene/_5o.frq | 1 + src/kundera-oracle-nosql/lucene/_5o.nrm | 1 + src/kundera-oracle-nosql/lucene/_5o.prx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_5o.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5o.tis | Bin 0 -> 1097 bytes src/kundera-oracle-nosql/lucene/_5q.fdt | Bin 0 -> 2262 bytes src/kundera-oracle-nosql/lucene/_5q.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_5q.fnm | 1 + src/kundera-oracle-nosql/lucene/_5q.frq | 1 + src/kundera-oracle-nosql/lucene/_5q.nrm | 1 + src/kundera-oracle-nosql/lucene/_5q.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5q.tis | Bin 0 -> 1125 bytes src/kundera-oracle-nosql/lucene/_5s.fdt | Bin 0 -> 2262 bytes src/kundera-oracle-nosql/lucene/_5s.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_5s.fnm | 1 + src/kundera-oracle-nosql/lucene/_5s.frq | 1 + src/kundera-oracle-nosql/lucene/_5s.nrm | 1 + src/kundera-oracle-nosql/lucene/_5s.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5s.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5s.tis | Bin 0 -> 1125 bytes src/kundera-oracle-nosql/lucene/_5u.fdt | Bin 0 -> 2262 bytes src/kundera-oracle-nosql/lucene/_5u.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_5u.fnm | 1 + src/kundera-oracle-nosql/lucene/_5u.frq | 1 + src/kundera-oracle-nosql/lucene/_5u.nrm | 1 + src/kundera-oracle-nosql/lucene/_5u.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5u.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5u.tis | Bin 0 -> 1125 bytes src/kundera-oracle-nosql/lucene/_5u_1.del | Bin 0 -> 31 bytes src/kundera-oracle-nosql/lucene/_5w.fdt | Bin 0 -> 1984 bytes src/kundera-oracle-nosql/lucene/_5w.fdx | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_5w.fnm | 1 + src/kundera-oracle-nosql/lucene/_5w.frq | 1 + src/kundera-oracle-nosql/lucene/_5w.nrm | 1 + src/kundera-oracle-nosql/lucene/_5w.prx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_5w.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5w.tis | Bin 0 -> 1097 bytes src/kundera-oracle-nosql/lucene/_5y.fdt | Bin 0 -> 2459 bytes src/kundera-oracle-nosql/lucene/_5y.fdx | Bin 0 -> 60 bytes src/kundera-oracle-nosql/lucene/_5y.fnm | 1 + src/kundera-oracle-nosql/lucene/_5y.frq | 1 + src/kundera-oracle-nosql/lucene/_5y.nrm | 1 + src/kundera-oracle-nosql/lucene/_5y.prx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_5y.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_5y.tis | Bin 0 -> 1377 bytes src/kundera-oracle-nosql/lucene/_6.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_6.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_6.fnm | 2 + src/kundera-oracle-nosql/lucene/_6.frq | 1 + src/kundera-oracle-nosql/lucene/_6.nrm | 1 + src/kundera-oracle-nosql/lucene/_6.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_6.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_60.fdt | Bin 0 -> 2978 bytes src/kundera-oracle-nosql/lucene/_60.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_60.fnm | 1 + src/kundera-oracle-nosql/lucene/_60.frq | 1 + src/kundera-oracle-nosql/lucene/_60.nrm | 1 + src/kundera-oracle-nosql/lucene/_60.prx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_60.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_60.tis | Bin 0 -> 1646 bytes src/kundera-oracle-nosql/lucene/_62.fdt | Bin 0 -> 3280 bytes src/kundera-oracle-nosql/lucene/_62.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_62.fnm | 1 + src/kundera-oracle-nosql/lucene/_62.frq | 1 + src/kundera-oracle-nosql/lucene/_62.nrm | 1 + src/kundera-oracle-nosql/lucene/_62.prx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_62.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_62.tis | Bin 0 -> 1681 bytes src/kundera-oracle-nosql/lucene/_62_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_64.fdt | Bin 0 -> 2805 bytes src/kundera-oracle-nosql/lucene/_64.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_64.fnm | 1 + src/kundera-oracle-nosql/lucene/_64.frq | 1 + src/kundera-oracle-nosql/lucene/_64.nrm | 1 + src/kundera-oracle-nosql/lucene/_64.prx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_64.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_64.tis | Bin 0 -> 1453 bytes src/kundera-oracle-nosql/lucene/_66.fdt | Bin 0 -> 3280 bytes src/kundera-oracle-nosql/lucene/_66.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_66.fnm | 1 + src/kundera-oracle-nosql/lucene/_66.frq | 1 + src/kundera-oracle-nosql/lucene/_66.nrm | 1 + src/kundera-oracle-nosql/lucene/_66.prx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_66.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_66.tis | Bin 0 -> 1681 bytes src/kundera-oracle-nosql/lucene/_68.fdt | Bin 0 -> 3280 bytes src/kundera-oracle-nosql/lucene/_68.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_68.fnm | 1 + src/kundera-oracle-nosql/lucene/_68.frq | 1 + src/kundera-oracle-nosql/lucene/_68.nrm | 1 + src/kundera-oracle-nosql/lucene/_68.prx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_68.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_68.tis | Bin 0 -> 1681 bytes src/kundera-oracle-nosql/lucene/_6a.fdt | Bin 0 -> 3280 bytes src/kundera-oracle-nosql/lucene/_6a.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_6a.fnm | 1 + src/kundera-oracle-nosql/lucene/_6a.frq | 1 + src/kundera-oracle-nosql/lucene/_6a.nrm | 1 + src/kundera-oracle-nosql/lucene/_6a.prx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_6a.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6a.tis | Bin 0 -> 1681 bytes src/kundera-oracle-nosql/lucene/_6a_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_6c.fdt | Bin 0 -> 2805 bytes src/kundera-oracle-nosql/lucene/_6c.fdx | Bin 0 -> 68 bytes src/kundera-oracle-nosql/lucene/_6c.fnm | 1 + src/kundera-oracle-nosql/lucene/_6c.frq | 1 + src/kundera-oracle-nosql/lucene/_6c.nrm | 1 + src/kundera-oracle-nosql/lucene/_6c.prx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_6c.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6c.tis | Bin 0 -> 1453 bytes src/kundera-oracle-nosql/lucene/_6e.fdt | Bin 0 -> 3106 bytes src/kundera-oracle-nosql/lucene/_6e.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_6e.fnm | 1 + src/kundera-oracle-nosql/lucene/_6e.frq | 1 + src/kundera-oracle-nosql/lucene/_6e.nrm | 1 + src/kundera-oracle-nosql/lucene/_6e.prx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_6e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6e.tis | Bin 0 -> 1599 bytes src/kundera-oracle-nosql/lucene/_6g.fdt | Bin 0 -> 3407 bytes src/kundera-oracle-nosql/lucene/_6g.fdx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_6g.fnm | 1 + src/kundera-oracle-nosql/lucene/_6g.frq | 1 + src/kundera-oracle-nosql/lucene/_6g.nrm | 1 + src/kundera-oracle-nosql/lucene/_6g.prx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_6g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6g.tis | Bin 0 -> 1691 bytes src/kundera-oracle-nosql/lucene/_6i.fdt | Bin 0 -> 3407 bytes src/kundera-oracle-nosql/lucene/_6i.fdx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_6i.fnm | 1 + src/kundera-oracle-nosql/lucene/_6i.frq | 1 + src/kundera-oracle-nosql/lucene/_6i.nrm | 1 + src/kundera-oracle-nosql/lucene/_6i.prx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_6i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6i.tis | Bin 0 -> 1663 bytes src/kundera-oracle-nosql/lucene/_6i_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_6k.fdt | Bin 0 -> 3106 bytes src/kundera-oracle-nosql/lucene/_6k.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_6k.fnm | 1 + src/kundera-oracle-nosql/lucene/_6k.frq | 1 + src/kundera-oracle-nosql/lucene/_6k.nrm | 1 + src/kundera-oracle-nosql/lucene/_6k.prx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_6k.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6k.tis | Bin 0 -> 1571 bytes src/kundera-oracle-nosql/lucene/_6m.fdt | Bin 0 -> 3106 bytes src/kundera-oracle-nosql/lucene/_6m.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_6m.fnm | 1 + src/kundera-oracle-nosql/lucene/_6m.frq | 1 + src/kundera-oracle-nosql/lucene/_6m.nrm | 1 + src/kundera-oracle-nosql/lucene/_6m.prx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_6m.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6m.tis | Bin 0 -> 1599 bytes src/kundera-oracle-nosql/lucene/_6o.fdt | Bin 0 -> 3407 bytes src/kundera-oracle-nosql/lucene/_6o.fdx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_6o.fnm | 1 + src/kundera-oracle-nosql/lucene/_6o.frq | 1 + src/kundera-oracle-nosql/lucene/_6o.nrm | 1 + src/kundera-oracle-nosql/lucene/_6o.prx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_6o.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6o.tis | Bin 0 -> 1691 bytes src/kundera-oracle-nosql/lucene/_6q.fdt | Bin 0 -> 3407 bytes src/kundera-oracle-nosql/lucene/_6q.fdx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_6q.fnm | 1 + src/kundera-oracle-nosql/lucene/_6q.frq | 1 + src/kundera-oracle-nosql/lucene/_6q.nrm | 1 + src/kundera-oracle-nosql/lucene/_6q.prx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_6q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6q.tis | Bin 0 -> 1663 bytes src/kundera-oracle-nosql/lucene/_6q_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_6s.fdt | Bin 0 -> 3106 bytes src/kundera-oracle-nosql/lucene/_6s.fdx | Bin 0 -> 76 bytes src/kundera-oracle-nosql/lucene/_6s.fnm | 1 + src/kundera-oracle-nosql/lucene/_6s.frq | 1 + src/kundera-oracle-nosql/lucene/_6s.nrm | 1 + src/kundera-oracle-nosql/lucene/_6s.prx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_6s.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6s.tis | Bin 0 -> 1571 bytes src/kundera-oracle-nosql/lucene/_6u.fdt | Bin 0 -> 3430 bytes src/kundera-oracle-nosql/lucene/_6u.fdx | Bin 0 -> 84 bytes src/kundera-oracle-nosql/lucene/_6u.fnm | 1 + src/kundera-oracle-nosql/lucene/_6u.frq | 1 + src/kundera-oracle-nosql/lucene/_6u.nrm | 1 + src/kundera-oracle-nosql/lucene/_6u.prx | Bin 0 -> 124 bytes src/kundera-oracle-nosql/lucene/_6u.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6u.tis | Bin 0 -> 1695 bytes src/kundera-oracle-nosql/lucene/_6w.fdt | Bin 0 -> 3734 bytes src/kundera-oracle-nosql/lucene/_6w.fdx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_6w.fnm | 1 + src/kundera-oracle-nosql/lucene/_6w.frq | 1 + src/kundera-oracle-nosql/lucene/_6w.nrm | 1 + src/kundera-oracle-nosql/lucene/_6w.prx | Bin 0 -> 136 bytes src/kundera-oracle-nosql/lucene/_6w.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6w.tis | Bin 0 -> 1713 bytes src/kundera-oracle-nosql/lucene/_6y.fdt | Bin 0 -> 4034 bytes src/kundera-oracle-nosql/lucene/_6y.fdx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_6y.fnm | 1 + src/kundera-oracle-nosql/lucene/_6y.frq | 1 + src/kundera-oracle-nosql/lucene/_6y.nrm | 1 + src/kundera-oracle-nosql/lucene/_6y.prx | Bin 0 -> 144 bytes src/kundera-oracle-nosql/lucene/_6y.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_6y.tis | Bin 0 -> 1724 bytes src/kundera-oracle-nosql/lucene/_6y_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_7.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_7.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_7.fnm | 2 + src/kundera-oracle-nosql/lucene/_7.frq | 1 + src/kundera-oracle-nosql/lucene/_7.nrm | 1 + src/kundera-oracle-nosql/lucene/_7.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_7.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_70.fdt | Bin 0 -> 3710 bytes src/kundera-oracle-nosql/lucene/_70.fdx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_70.fnm | 1 + src/kundera-oracle-nosql/lucene/_70.frq | 1 + src/kundera-oracle-nosql/lucene/_70.nrm | 1 + src/kundera-oracle-nosql/lucene/_70.prx | Bin 0 -> 136 bytes src/kundera-oracle-nosql/lucene/_70.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_70.tis | Bin 0 -> 1652 bytes src/kundera-oracle-nosql/lucene/_72.fdt | Bin 0 -> 4034 bytes src/kundera-oracle-nosql/lucene/_72.fdx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_72.fnm | 1 + src/kundera-oracle-nosql/lucene/_72.frq | 1 + src/kundera-oracle-nosql/lucene/_72.nrm | 1 + src/kundera-oracle-nosql/lucene/_72.prx | Bin 0 -> 144 bytes src/kundera-oracle-nosql/lucene/_72.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_72.tis | Bin 0 -> 1724 bytes src/kundera-oracle-nosql/lucene/_74.fdt | Bin 0 -> 4034 bytes src/kundera-oracle-nosql/lucene/_74.fdx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_74.fnm | 1 + src/kundera-oracle-nosql/lucene/_74.frq | 1 + src/kundera-oracle-nosql/lucene/_74.nrm | 1 + src/kundera-oracle-nosql/lucene/_74.prx | Bin 0 -> 144 bytes src/kundera-oracle-nosql/lucene/_74.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_74.tis | Bin 0 -> 1724 bytes src/kundera-oracle-nosql/lucene/_76.fdt | Bin 0 -> 4034 bytes src/kundera-oracle-nosql/lucene/_76.fdx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_76.fnm | 1 + src/kundera-oracle-nosql/lucene/_76.frq | 1 + src/kundera-oracle-nosql/lucene/_76.nrm | 1 + src/kundera-oracle-nosql/lucene/_76.prx | Bin 0 -> 144 bytes src/kundera-oracle-nosql/lucene/_76.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_76.tis | Bin 0 -> 1724 bytes src/kundera-oracle-nosql/lucene/_76_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_78.fdt | Bin 0 -> 3710 bytes src/kundera-oracle-nosql/lucene/_78.fdx | Bin 0 -> 92 bytes src/kundera-oracle-nosql/lucene/_78.fnm | 1 + src/kundera-oracle-nosql/lucene/_78.frq | 1 + src/kundera-oracle-nosql/lucene/_78.nrm | 1 + src/kundera-oracle-nosql/lucene/_78.prx | Bin 0 -> 136 bytes src/kundera-oracle-nosql/lucene/_78.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_78.tis | Bin 0 -> 1652 bytes src/kundera-oracle-nosql/lucene/_7a.fdt | Bin 0 -> 4083 bytes src/kundera-oracle-nosql/lucene/_7a.fdx | Bin 0 -> 100 bytes src/kundera-oracle-nosql/lucene/_7a.fnm | 1 + src/kundera-oracle-nosql/lucene/_7a.frq | 1 + src/kundera-oracle-nosql/lucene/_7a.nrm | 1 + src/kundera-oracle-nosql/lucene/_7a.prx | Bin 0 -> 144 bytes src/kundera-oracle-nosql/lucene/_7a.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7a.tis | Bin 0 -> 1840 bytes src/kundera-oracle-nosql/lucene/_7c.fdt | Bin 0 -> 4400 bytes src/kundera-oracle-nosql/lucene/_7c.fdx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_7c.fnm | 1 + src/kundera-oracle-nosql/lucene/_7c.frq | 1 + src/kundera-oracle-nosql/lucene/_7c.nrm | 1 + src/kundera-oracle-nosql/lucene/_7c.prx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_7c.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7c.tis | Bin 0 -> 1915 bytes src/kundera-oracle-nosql/lucene/_7e.fdt | Bin 0 -> 4717 bytes src/kundera-oracle-nosql/lucene/_7e.fdx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_7e.fnm | 1 + src/kundera-oracle-nosql/lucene/_7e.frq | 1 + src/kundera-oracle-nosql/lucene/_7e.nrm | 1 + src/kundera-oracle-nosql/lucene/_7e.prx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_7e.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7e.tis | Bin 0 -> 1961 bytes src/kundera-oracle-nosql/lucene/_7e_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_7g.fdt | Bin 0 -> 4344 bytes src/kundera-oracle-nosql/lucene/_7g.fdx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_7g.fnm | 1 + src/kundera-oracle-nosql/lucene/_7g.frq | 1 + src/kundera-oracle-nosql/lucene/_7g.nrm | 1 + src/kundera-oracle-nosql/lucene/_7g.prx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_7g.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7g.tis | Bin 0 -> 1854 bytes src/kundera-oracle-nosql/lucene/_7i.fdt | Bin 0 -> 4717 bytes src/kundera-oracle-nosql/lucene/_7i.fdx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_7i.fnm | 1 + src/kundera-oracle-nosql/lucene/_7i.frq | 1 + src/kundera-oracle-nosql/lucene/_7i.nrm | 1 + src/kundera-oracle-nosql/lucene/_7i.prx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_7i.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7i.tis | Bin 0 -> 1961 bytes src/kundera-oracle-nosql/lucene/_7k.fdt | Bin 0 -> 4717 bytes src/kundera-oracle-nosql/lucene/_7k.fdx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_7k.fnm | 1 + src/kundera-oracle-nosql/lucene/_7k.frq | 1 + src/kundera-oracle-nosql/lucene/_7k.nrm | 1 + src/kundera-oracle-nosql/lucene/_7k.prx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_7k.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7k.tis | Bin 0 -> 1961 bytes src/kundera-oracle-nosql/lucene/_7m.fdt | Bin 0 -> 4717 bytes src/kundera-oracle-nosql/lucene/_7m.fdx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_7m.fnm | 1 + src/kundera-oracle-nosql/lucene/_7m.frq | 1 + src/kundera-oracle-nosql/lucene/_7m.nrm | 1 + src/kundera-oracle-nosql/lucene/_7m.prx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_7m.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7m.tis | Bin 0 -> 1961 bytes src/kundera-oracle-nosql/lucene/_7m_1.del | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/_7o.fdt | Bin 0 -> 4344 bytes src/kundera-oracle-nosql/lucene/_7o.fdx | Bin 0 -> 108 bytes src/kundera-oracle-nosql/lucene/_7o.fnm | 1 + src/kundera-oracle-nosql/lucene/_7o.frq | 1 + src/kundera-oracle-nosql/lucene/_7o.nrm | 1 + src/kundera-oracle-nosql/lucene/_7o.prx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_7o.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_7o.tis | Bin 0 -> 1854 bytes src/kundera-oracle-nosql/lucene/_7q.fdt | Bin 0 -> 4703 bytes src/kundera-oracle-nosql/lucene/_7q.fdx | Bin 0 -> 116 bytes src/kundera-oracle-nosql/lucene/_7q.fnm | 1 + src/kundera-oracle-nosql/lucene/_7q.frq | 4 + src/kundera-oracle-nosql/lucene/_7q.nrm | 1 + src/kundera-oracle-nosql/lucene/_7q.prx | Bin 0 -> 184 bytes src/kundera-oracle-nosql/lucene/_7q.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_7q.tis | Bin 0 -> 2034 bytes src/kundera-oracle-nosql/lucene/_7s.fdt | Bin 0 -> 4981 bytes src/kundera-oracle-nosql/lucene/_7s.fdx | Bin 0 -> 124 bytes src/kundera-oracle-nosql/lucene/_7s.fnm | 1 + src/kundera-oracle-nosql/lucene/_7s.frq | 4 + src/kundera-oracle-nosql/lucene/_7s.nrm | 1 + src/kundera-oracle-nosql/lucene/_7s.prx | Bin 0 -> 192 bytes src/kundera-oracle-nosql/lucene/_7s.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_7s.tis | Bin 0 -> 2122 bytes src/kundera-oracle-nosql/lucene/_7u.fdt | Bin 0 -> 5267 bytes src/kundera-oracle-nosql/lucene/_7u.fdx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_7u.fnm | 1 + src/kundera-oracle-nosql/lucene/_7u.frq | 4 + src/kundera-oracle-nosql/lucene/_7u.nrm | 1 + src/kundera-oracle-nosql/lucene/_7u.prx | Bin 0 -> 200 bytes src/kundera-oracle-nosql/lucene/_7u.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_7u.tis | Bin 0 -> 2174 bytes src/kundera-oracle-nosql/lucene/_7w.fdt | Bin 0 -> 5549 bytes src/kundera-oracle-nosql/lucene/_7w.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_7w.fnm | 1 + src/kundera-oracle-nosql/lucene/_7w.frq | 4 + src/kundera-oracle-nosql/lucene/_7w.nrm | 1 + src/kundera-oracle-nosql/lucene/_7w.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_7w.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_7w.tis | Bin 0 -> 2219 bytes src/kundera-oracle-nosql/lucene/_7w_1.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_7y.fdt | Bin 0 -> 5271 bytes src/kundera-oracle-nosql/lucene/_7y.fdx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_7y.fnm | 1 + src/kundera-oracle-nosql/lucene/_7y.frq | 4 + src/kundera-oracle-nosql/lucene/_7y.nrm | 1 + src/kundera-oracle-nosql/lucene/_7y.prx | Bin 0 -> 200 bytes src/kundera-oracle-nosql/lucene/_7y.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_7y.tis | Bin 0 -> 2175 bytes src/kundera-oracle-nosql/lucene/_80.fdt | Bin 0 -> 5549 bytes src/kundera-oracle-nosql/lucene/_80.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_80.fnm | 1 + src/kundera-oracle-nosql/lucene/_80.frq | 4 + src/kundera-oracle-nosql/lucene/_80.nrm | 1 + src/kundera-oracle-nosql/lucene/_80.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_80.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_80.tis | Bin 0 -> 2219 bytes src/kundera-oracle-nosql/lucene/_82.fdt | Bin 0 -> 5549 bytes src/kundera-oracle-nosql/lucene/_82.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_82.fnm | 1 + src/kundera-oracle-nosql/lucene/_82.frq | 4 + src/kundera-oracle-nosql/lucene/_82.nrm | 1 + src/kundera-oracle-nosql/lucene/_82.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_82.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_82.tis | Bin 0 -> 2219 bytes src/kundera-oracle-nosql/lucene/_84.fdt | Bin 0 -> 5549 bytes src/kundera-oracle-nosql/lucene/_84.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_84.fnm | 1 + src/kundera-oracle-nosql/lucene/_84.frq | 4 + src/kundera-oracle-nosql/lucene/_84.nrm | 1 + src/kundera-oracle-nosql/lucene/_84.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_84.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_84.tis | Bin 0 -> 2219 bytes src/kundera-oracle-nosql/lucene/_84_1.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_86.fdt | Bin 0 -> 5271 bytes src/kundera-oracle-nosql/lucene/_86.fdx | Bin 0 -> 132 bytes src/kundera-oracle-nosql/lucene/_86.fnm | 1 + src/kundera-oracle-nosql/lucene/_86.frq | 4 + src/kundera-oracle-nosql/lucene/_86.nrm | 1 + src/kundera-oracle-nosql/lucene/_86.prx | Bin 0 -> 200 bytes src/kundera-oracle-nosql/lucene/_86.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_86.tis | Bin 0 -> 2175 bytes src/kundera-oracle-nosql/lucene/_88.fdt | Bin 0 -> 5560 bytes src/kundera-oracle-nosql/lucene/_88.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_88.fnm | 1 + src/kundera-oracle-nosql/lucene/_88.frq | 4 + src/kundera-oracle-nosql/lucene/_88.nrm | 1 + src/kundera-oracle-nosql/lucene/_88.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_88.tii | Bin 0 -> 55 bytes src/kundera-oracle-nosql/lucene/_88.tis | Bin 0 -> 2275 bytes src/kundera-oracle-nosql/lucene/_8a.fdt | Bin 0 -> 5560 bytes src/kundera-oracle-nosql/lucene/_8a.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_8a.fnm | 1 + src/kundera-oracle-nosql/lucene/_8a.frq | 4 + src/kundera-oracle-nosql/lucene/_8a.nrm | 1 + src/kundera-oracle-nosql/lucene/_8a.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_8a.tii | Bin 0 -> 55 bytes src/kundera-oracle-nosql/lucene/_8a.tis | Bin 0 -> 2275 bytes src/kundera-oracle-nosql/lucene/_8c.fdt | Bin 0 -> 5638 bytes src/kundera-oracle-nosql/lucene/_8c.fdx | Bin 0 -> 140 bytes src/kundera-oracle-nosql/lucene/_8c.fnm | 1 + src/kundera-oracle-nosql/lucene/_8c.frq | 4 + src/kundera-oracle-nosql/lucene/_8c.nrm | 1 + src/kundera-oracle-nosql/lucene/_8c.prx | Bin 0 -> 208 bytes src/kundera-oracle-nosql/lucene/_8c.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8c.tis | Bin 0 -> 2331 bytes src/kundera-oracle-nosql/lucene/_8e.fdt | Bin 0 -> 5949 bytes src/kundera-oracle-nosql/lucene/_8e.fdx | Bin 0 -> 148 bytes src/kundera-oracle-nosql/lucene/_8e.fnm | 1 + src/kundera-oracle-nosql/lucene/_8e.frq | 4 + src/kundera-oracle-nosql/lucene/_8e.nrm | 1 + src/kundera-oracle-nosql/lucene/_8e.prx | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_8e.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_8e.tis | Bin 0 -> 2352 bytes src/kundera-oracle-nosql/lucene/_8g.fdt | Bin 0 -> 6260 bytes src/kundera-oracle-nosql/lucene/_8g.fdx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_8g.fnm | 1 + src/kundera-oracle-nosql/lucene/_8g.frq | 4 + src/kundera-oracle-nosql/lucene/_8g.nrm | 1 + src/kundera-oracle-nosql/lucene/_8g.prx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_8g.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8g.tis | Bin 0 -> 2365 bytes src/kundera-oracle-nosql/lucene/_8g_1.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_8i.fdt | Bin 0 -> 5893 bytes src/kundera-oracle-nosql/lucene/_8i.fdx | Bin 0 -> 148 bytes src/kundera-oracle-nosql/lucene/_8i.fnm | 1 + src/kundera-oracle-nosql/lucene/_8i.frq | 4 + src/kundera-oracle-nosql/lucene/_8i.nrm | 1 + src/kundera-oracle-nosql/lucene/_8i.prx | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_8i.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8i.tis | Bin 0 -> 2260 bytes src/kundera-oracle-nosql/lucene/_8k.fdt | Bin 0 -> 6260 bytes src/kundera-oracle-nosql/lucene/_8k.fdx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_8k.fnm | 1 + src/kundera-oracle-nosql/lucene/_8k.frq | 4 + src/kundera-oracle-nosql/lucene/_8k.nrm | 1 + src/kundera-oracle-nosql/lucene/_8k.prx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_8k.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8k.tis | Bin 0 -> 2365 bytes src/kundera-oracle-nosql/lucene/_8m.fdt | Bin 0 -> 6260 bytes src/kundera-oracle-nosql/lucene/_8m.fdx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_8m.fnm | 1 + src/kundera-oracle-nosql/lucene/_8m.frq | 4 + src/kundera-oracle-nosql/lucene/_8m.nrm | 1 + src/kundera-oracle-nosql/lucene/_8m.prx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_8m.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8m.tis | Bin 0 -> 2365 bytes src/kundera-oracle-nosql/lucene/_8o.fdt | Bin 0 -> 6260 bytes src/kundera-oracle-nosql/lucene/_8o.fdx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_8o.fnm | 1 + src/kundera-oracle-nosql/lucene/_8o.frq | 4 + src/kundera-oracle-nosql/lucene/_8o.nrm | 1 + src/kundera-oracle-nosql/lucene/_8o.prx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_8o.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8o.tis | Bin 0 -> 2365 bytes src/kundera-oracle-nosql/lucene/_8o_1.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_8q.fdt | Bin 0 -> 5893 bytes src/kundera-oracle-nosql/lucene/_8q.fdx | Bin 0 -> 148 bytes src/kundera-oracle-nosql/lucene/_8q.fnm | 1 + src/kundera-oracle-nosql/lucene/_8q.frq | 4 + src/kundera-oracle-nosql/lucene/_8q.nrm | 1 + src/kundera-oracle-nosql/lucene/_8q.prx | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_8q.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_8q.tis | Bin 0 -> 2260 bytes src/kundera-oracle-nosql/lucene/_8s.fdt | Bin 0 -> 6246 bytes src/kundera-oracle-nosql/lucene/_8s.fdx | Bin 0 -> 156 bytes src/kundera-oracle-nosql/lucene/_8s.fnm | 1 + src/kundera-oracle-nosql/lucene/_8s.frq | 4 + src/kundera-oracle-nosql/lucene/_8s.nrm | 1 + src/kundera-oracle-nosql/lucene/_8s.prx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_8s.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_8s.tis | Bin 0 -> 2428 bytes src/kundera-oracle-nosql/lucene/_8u.fdt | Bin 0 -> 6551 bytes src/kundera-oracle-nosql/lucene/_8u.fdx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_8u.fnm | 1 + src/kundera-oracle-nosql/lucene/_8u.frq | 4 + src/kundera-oracle-nosql/lucene/_8u.nrm | 1 + src/kundera-oracle-nosql/lucene/_8u.prx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_8u.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_8u.tis | Bin 0 -> 2442 bytes src/kundera-oracle-nosql/lucene/_8w.fdt | Bin 0 -> 6900 bytes src/kundera-oracle-nosql/lucene/_8w.fdx | Bin 0 -> 172 bytes src/kundera-oracle-nosql/lucene/_8w.fnm | 1 + src/kundera-oracle-nosql/lucene/_8w.frq | 4 + src/kundera-oracle-nosql/lucene/_8w.nrm | 1 + src/kundera-oracle-nosql/lucene/_8w.prx | Bin 0 -> 244 bytes src/kundera-oracle-nosql/lucene/_8w.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_8w.tis | Bin 0 -> 2470 bytes src/kundera-oracle-nosql/lucene/_8w_1.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_8y.fdt | Bin 0 -> 6551 bytes src/kundera-oracle-nosql/lucene/_8y.fdx | Bin 0 -> 164 bytes src/kundera-oracle-nosql/lucene/_8y.fnm | 1 + src/kundera-oracle-nosql/lucene/_8y.frq | 4 + src/kundera-oracle-nosql/lucene/_8y.nrm | 1 + src/kundera-oracle-nosql/lucene/_8y.prx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_8y.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_8y.tis | Bin 0 -> 2442 bytes src/kundera-oracle-nosql/lucene/_9.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_9.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_9.fnm | 2 + src/kundera-oracle-nosql/lucene/_9.frq | 1 + src/kundera-oracle-nosql/lucene/_9.nrm | 1 + src/kundera-oracle-nosql/lucene/_9.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_9.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_9.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_90.fdt | Bin 0 -> 6852 bytes src/kundera-oracle-nosql/lucene/_90.fdx | Bin 0 -> 172 bytes src/kundera-oracle-nosql/lucene/_90.fnm | 1 + src/kundera-oracle-nosql/lucene/_90.frq | 4 + src/kundera-oracle-nosql/lucene/_90.nrm | 1 + src/kundera-oracle-nosql/lucene/_90.prx | Bin 0 -> 244 bytes src/kundera-oracle-nosql/lucene/_90.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_90.tis | Bin 0 -> 2558 bytes src/kundera-oracle-nosql/lucene/_92.fdt | Bin 0 -> 6852 bytes src/kundera-oracle-nosql/lucene/_92.fdx | Bin 0 -> 172 bytes src/kundera-oracle-nosql/lucene/_92.fnm | 1 + src/kundera-oracle-nosql/lucene/_92.frq | 4 + src/kundera-oracle-nosql/lucene/_92.nrm | 1 + src/kundera-oracle-nosql/lucene/_92.prx | Bin 0 -> 244 bytes src/kundera-oracle-nosql/lucene/_92.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_92.tis | Bin 0 -> 2558 bytes src/kundera-oracle-nosql/lucene/_94.fdt | Bin 0 -> 6915 bytes src/kundera-oracle-nosql/lucene/_94.fdx | Bin 0 -> 172 bytes src/kundera-oracle-nosql/lucene/_94.fnm | 1 + src/kundera-oracle-nosql/lucene/_94.frq | 4 + src/kundera-oracle-nosql/lucene/_94.nrm | 1 + src/kundera-oracle-nosql/lucene/_94.prx | Bin 0 -> 272 bytes src/kundera-oracle-nosql/lucene/_94.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_94.tis | Bin 0 -> 2630 bytes src/kundera-oracle-nosql/lucene/_96.fdt | Bin 0 -> 7217 bytes src/kundera-oracle-nosql/lucene/_96.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_96.fnm | 1 + src/kundera-oracle-nosql/lucene/_96.frq | 4 + src/kundera-oracle-nosql/lucene/_96.nrm | 1 + src/kundera-oracle-nosql/lucene/_96.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_96.tii | Bin 0 -> 51 bytes src/kundera-oracle-nosql/lucene/_96.tis | Bin 0 -> 2744 bytes src/kundera-oracle-nosql/lucene/_98.fdt | Bin 0 -> 7217 bytes src/kundera-oracle-nosql/lucene/_98.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_98.fnm | 1 + src/kundera-oracle-nosql/lucene/_98.frq | 4 + src/kundera-oracle-nosql/lucene/_98.nrm | 1 + src/kundera-oracle-nosql/lucene/_98.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_98.tii | Bin 0 -> 51 bytes src/kundera-oracle-nosql/lucene/_98.tis | Bin 0 -> 2744 bytes src/kundera-oracle-nosql/lucene/_9a.fdt | Bin 0 -> 7211 bytes src/kundera-oracle-nosql/lucene/_9a.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9a.fnm | 1 + src/kundera-oracle-nosql/lucene/_9a.frq | 4 + src/kundera-oracle-nosql/lucene/_9a.nrm | 1 + src/kundera-oracle-nosql/lucene/_9a.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9a.tii | Bin 0 -> 51 bytes src/kundera-oracle-nosql/lucene/_9a.tis | Bin 0 -> 2736 bytes src/kundera-oracle-nosql/lucene/_9c.fdt | Bin 0 -> 7211 bytes src/kundera-oracle-nosql/lucene/_9c.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9c.fnm | 1 + src/kundera-oracle-nosql/lucene/_9c.frq | 4 + src/kundera-oracle-nosql/lucene/_9c.nrm | 1 + src/kundera-oracle-nosql/lucene/_9c.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9c.tii | Bin 0 -> 51 bytes src/kundera-oracle-nosql/lucene/_9c.tis | Bin 0 -> 2736 bytes src/kundera-oracle-nosql/lucene/_9e.fdt | Bin 0 -> 7213 bytes src/kundera-oracle-nosql/lucene/_9e.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9e.fnm | 1 + src/kundera-oracle-nosql/lucene/_9e.frq | 4 + src/kundera-oracle-nosql/lucene/_9e.nrm | 1 + src/kundera-oracle-nosql/lucene/_9e.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9e.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9e.tis | Bin 0 -> 2743 bytes src/kundera-oracle-nosql/lucene/_9g.fdt | Bin 0 -> 7515 bytes src/kundera-oracle-nosql/lucene/_9g.fdx | Bin 0 -> 188 bytes src/kundera-oracle-nosql/lucene/_9g.fnm | 1 + src/kundera-oracle-nosql/lucene/_9g.frq | 4 + src/kundera-oracle-nosql/lucene/_9g.nrm | 1 + src/kundera-oracle-nosql/lucene/_9g.prx | Bin 0 -> 288 bytes src/kundera-oracle-nosql/lucene/_9g.tii | Bin 0 -> 57 bytes src/kundera-oracle-nosql/lucene/_9g.tis | Bin 0 -> 2787 bytes src/kundera-oracle-nosql/lucene/_9g_2.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_9h.cfs | Bin 0 -> 1670 bytes src/kundera-oracle-nosql/lucene/_9i.fdt | Bin 0 -> 7213 bytes src/kundera-oracle-nosql/lucene/_9i.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9i.fnm | 1 + src/kundera-oracle-nosql/lucene/_9i.frq | 4 + src/kundera-oracle-nosql/lucene/_9i.nrm | 1 + src/kundera-oracle-nosql/lucene/_9i.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9i.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9i.tis | Bin 0 -> 2743 bytes src/kundera-oracle-nosql/lucene/_9k.fdt | Bin 0 -> 7213 bytes src/kundera-oracle-nosql/lucene/_9k.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9k.fnm | 1 + src/kundera-oracle-nosql/lucene/_9k.frq | 4 + src/kundera-oracle-nosql/lucene/_9k.nrm | 1 + src/kundera-oracle-nosql/lucene/_9k.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9k.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9k.tis | Bin 0 -> 2743 bytes src/kundera-oracle-nosql/lucene/_9m.fdt | Bin 0 -> 7515 bytes src/kundera-oracle-nosql/lucene/_9m.fdx | Bin 0 -> 188 bytes src/kundera-oracle-nosql/lucene/_9m.fnm | 1 + src/kundera-oracle-nosql/lucene/_9m.frq | 4 + src/kundera-oracle-nosql/lucene/_9m.nrm | 1 + src/kundera-oracle-nosql/lucene/_9m.prx | Bin 0 -> 288 bytes src/kundera-oracle-nosql/lucene/_9m.tii | Bin 0 -> 57 bytes src/kundera-oracle-nosql/lucene/_9m.tis | Bin 0 -> 2787 bytes src/kundera-oracle-nosql/lucene/_9m_2.del | Bin 0 -> 33 bytes src/kundera-oracle-nosql/lucene/_9n.cfs | Bin 0 -> 1670 bytes src/kundera-oracle-nosql/lucene/_9o.fdt | Bin 0 -> 7213 bytes src/kundera-oracle-nosql/lucene/_9o.fdx | Bin 0 -> 180 bytes src/kundera-oracle-nosql/lucene/_9o.fnm | 1 + src/kundera-oracle-nosql/lucene/_9o.frq | 4 + src/kundera-oracle-nosql/lucene/_9o.nrm | 1 + src/kundera-oracle-nosql/lucene/_9o.prx | Bin 0 -> 280 bytes src/kundera-oracle-nosql/lucene/_9o.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9o.tis | Bin 0 -> 2743 bytes src/kundera-oracle-nosql/lucene/_9q.fdt | Bin 0 -> 7497 bytes src/kundera-oracle-nosql/lucene/_9q.fdx | Bin 0 -> 188 bytes src/kundera-oracle-nosql/lucene/_9q.fnm | 1 + src/kundera-oracle-nosql/lucene/_9q.frq | 4 + src/kundera-oracle-nosql/lucene/_9q.nrm | 1 + src/kundera-oracle-nosql/lucene/_9q.prx | Bin 0 -> 296 bytes src/kundera-oracle-nosql/lucene/_9q.tii | Bin 0 -> 64 bytes src/kundera-oracle-nosql/lucene/_9q.tis | Bin 0 -> 2791 bytes src/kundera-oracle-nosql/lucene/_9s.fdt | Bin 0 -> 7782 bytes src/kundera-oracle-nosql/lucene/_9s.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_9s.fnm | 1 + src/kundera-oracle-nosql/lucene/_9s.frq | 4 + src/kundera-oracle-nosql/lucene/_9s.nrm | 1 + src/kundera-oracle-nosql/lucene/_9s.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_9s.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9s.tis | Bin 0 -> 2885 bytes src/kundera-oracle-nosql/lucene/_9u.fdt | Bin 0 -> 7782 bytes src/kundera-oracle-nosql/lucene/_9u.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_9u.fnm | 1 + src/kundera-oracle-nosql/lucene/_9u.frq | 4 + src/kundera-oracle-nosql/lucene/_9u.nrm | 1 + src/kundera-oracle-nosql/lucene/_9u.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_9u.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9u.tis | Bin 0 -> 2885 bytes src/kundera-oracle-nosql/lucene/_9w.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_9w.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_9w.fnm | 1 + src/kundera-oracle-nosql/lucene/_9w.frq | 4 + src/kundera-oracle-nosql/lucene/_9w.nrm | 1 + src/kundera-oracle-nosql/lucene/_9w.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_9w.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_9w.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_9y.fdt | Bin 0 -> 8109 bytes src/kundera-oracle-nosql/lucene/_9y.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_9y.fnm | 1 + src/kundera-oracle-nosql/lucene/_9y.frq | 4 + src/kundera-oracle-nosql/lucene/_9y.nrm | 1 + src/kundera-oracle-nosql/lucene/_9y.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_9y.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_9y.tis | Bin 0 -> 2901 bytes src/kundera-oracle-nosql/lucene/_9y_2.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_9z.cfs | Bin 0 -> 1784 bytes src/kundera-oracle-nosql/lucene/_a0.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_a0.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_a0.fnm | 1 + src/kundera-oracle-nosql/lucene/_a0.frq | 4 + src/kundera-oracle-nosql/lucene/_a0.nrm | 1 + src/kundera-oracle-nosql/lucene/_a0.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_a0.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_a0.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_a2.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_a2.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_a2.fnm | 1 + src/kundera-oracle-nosql/lucene/_a2.frq | 4 + src/kundera-oracle-nosql/lucene/_a2.nrm | 1 + src/kundera-oracle-nosql/lucene/_a2.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_a2.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_a2.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_a4.fdt | Bin 0 -> 8109 bytes src/kundera-oracle-nosql/lucene/_a4.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_a4.fnm | 1 + src/kundera-oracle-nosql/lucene/_a4.frq | 4 + src/kundera-oracle-nosql/lucene/_a4.nrm | 1 + src/kundera-oracle-nosql/lucene/_a4.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_a4.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_a4.tis | Bin 0 -> 2901 bytes src/kundera-oracle-nosql/lucene/_a4_2.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_a5.cfs | Bin 0 -> 1784 bytes src/kundera-oracle-nosql/lucene/_a6.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_a6.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_a6.fnm | 1 + src/kundera-oracle-nosql/lucene/_a6.frq | 4 + src/kundera-oracle-nosql/lucene/_a6.nrm | 1 + src/kundera-oracle-nosql/lucene/_a6.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_a6.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_a6.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_a8.fdt | Bin 0 -> 8080 bytes src/kundera-oracle-nosql/lucene/_a8.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_a8.fnm | 1 + src/kundera-oracle-nosql/lucene/_a8.frq | 4 + src/kundera-oracle-nosql/lucene/_a8.nrm | 1 + src/kundera-oracle-nosql/lucene/_a8.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_a8.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_a8.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_aa.fdt | Bin 0 -> 8072 bytes src/kundera-oracle-nosql/lucene/_aa.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_aa.fnm | 1 + src/kundera-oracle-nosql/lucene/_aa.frq | 4 + src/kundera-oracle-nosql/lucene/_aa.nrm | 1 + src/kundera-oracle-nosql/lucene/_aa.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_aa.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_aa.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_ac.fdt | Bin 0 -> 8072 bytes src/kundera-oracle-nosql/lucene/_ac.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ac.fnm | 1 + src/kundera-oracle-nosql/lucene/_ac.frq | 4 + src/kundera-oracle-nosql/lucene/_ac.nrm | 1 + src/kundera-oracle-nosql/lucene/_ac.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ac.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ac.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_ac_1.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_ae.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_ae.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_ae.fnm | 1 + src/kundera-oracle-nosql/lucene/_ae.frq | 4 + src/kundera-oracle-nosql/lucene/_ae.nrm | 1 + src/kundera-oracle-nosql/lucene/_ae.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_ae.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_ae.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_ag.fdt | Bin 0 -> 8080 bytes src/kundera-oracle-nosql/lucene/_ag.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ag.fnm | 1 + src/kundera-oracle-nosql/lucene/_ag.frq | 4 + src/kundera-oracle-nosql/lucene/_ag.nrm | 1 + src/kundera-oracle-nosql/lucene/_ag.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ag.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ag.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_ai.fdt | Bin 0 -> 8072 bytes src/kundera-oracle-nosql/lucene/_ai.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ai.fnm | 1 + src/kundera-oracle-nosql/lucene/_ai.frq | 4 + src/kundera-oracle-nosql/lucene/_ai.nrm | 1 + src/kundera-oracle-nosql/lucene/_ai.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ai.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ai.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_ak.fdt | Bin 0 -> 8072 bytes src/kundera-oracle-nosql/lucene/_ak.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ak.fnm | 1 + src/kundera-oracle-nosql/lucene/_ak.frq | 4 + src/kundera-oracle-nosql/lucene/_ak.nrm | 1 + src/kundera-oracle-nosql/lucene/_ak.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ak.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ak.tis | Bin 0 -> 2917 bytes src/kundera-oracle-nosql/lucene/_ak_1.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_am.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_am.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_am.fnm | 1 + src/kundera-oracle-nosql/lucene/_am.frq | 4 + src/kundera-oracle-nosql/lucene/_am.nrm | 1 + src/kundera-oracle-nosql/lucene/_am.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_am.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_am.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_ao.fdt | Bin 0 -> 8065 bytes src/kundera-oracle-nosql/lucene/_ao.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ao.fnm | 1 + src/kundera-oracle-nosql/lucene/_ao.frq | 4 + src/kundera-oracle-nosql/lucene/_ao.nrm | 1 + src/kundera-oracle-nosql/lucene/_ao.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ao.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ao.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_aq.fdt | Bin 0 -> 8057 bytes src/kundera-oracle-nosql/lucene/_aq.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_aq.fnm | 1 + src/kundera-oracle-nosql/lucene/_aq.frq | 4 + src/kundera-oracle-nosql/lucene/_aq.nrm | 1 + src/kundera-oracle-nosql/lucene/_aq.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_aq.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_aq.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_as.fdt | Bin 0 -> 8057 bytes src/kundera-oracle-nosql/lucene/_as.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_as.fnm | 1 + src/kundera-oracle-nosql/lucene/_as.frq | 4 + src/kundera-oracle-nosql/lucene/_as.nrm | 1 + src/kundera-oracle-nosql/lucene/_as.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_as.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_as.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_as_1.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_au.fdt | Bin 0 -> 7801 bytes src/kundera-oracle-nosql/lucene/_au.fdx | Bin 0 -> 196 bytes src/kundera-oracle-nosql/lucene/_au.fnm | 1 + src/kundera-oracle-nosql/lucene/_au.frq | 4 + src/kundera-oracle-nosql/lucene/_au.nrm | 1 + src/kundera-oracle-nosql/lucene/_au.prx | Bin 0 -> 304 bytes src/kundera-oracle-nosql/lucene/_au.tii | Bin 0 -> 53 bytes src/kundera-oracle-nosql/lucene/_au.tis | Bin 0 -> 2857 bytes src/kundera-oracle-nosql/lucene/_aw.fdt | Bin 0 -> 8065 bytes src/kundera-oracle-nosql/lucene/_aw.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_aw.fnm | 1 + src/kundera-oracle-nosql/lucene/_aw.frq | 4 + src/kundera-oracle-nosql/lucene/_aw.nrm | 1 + src/kundera-oracle-nosql/lucene/_aw.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_aw.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_aw.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_ay.fdt | Bin 0 -> 8057 bytes src/kundera-oracle-nosql/lucene/_ay.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_ay.fnm | 1 + src/kundera-oracle-nosql/lucene/_ay.frq | 4 + src/kundera-oracle-nosql/lucene/_ay.nrm | 1 + src/kundera-oracle-nosql/lucene/_ay.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_ay.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_ay.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_b.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_b.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_b.fnm | 2 + src/kundera-oracle-nosql/lucene/_b.frq | 1 + src/kundera-oracle-nosql/lucene/_b.nrm | 1 + src/kundera-oracle-nosql/lucene/_b.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_b.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_b.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_b0.fdt | Bin 0 -> 8057 bytes src/kundera-oracle-nosql/lucene/_b0.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_b0.fnm | 1 + src/kundera-oracle-nosql/lucene/_b0.frq | 4 + src/kundera-oracle-nosql/lucene/_b0.nrm | 1 + src/kundera-oracle-nosql/lucene/_b0.prx | Bin 0 -> 308 bytes src/kundera-oracle-nosql/lucene/_b0.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_b0.tis | Bin 0 -> 2897 bytes src/kundera-oracle-nosql/lucene/_b0_1.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_b3.fdt | Bin 0 -> 8092 bytes src/kundera-oracle-nosql/lucene/_b3.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_b3.fnm | 1 + src/kundera-oracle-nosql/lucene/_b3.frq | 4 + src/kundera-oracle-nosql/lucene/_b3.nrm | 1 + src/kundera-oracle-nosql/lucene/_b3.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_b3.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_b3.tis | Bin 0 -> 2959 bytes src/kundera-oracle-nosql/lucene/_b5.fdt | Bin 0 -> 8092 bytes src/kundera-oracle-nosql/lucene/_b5.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_b5.fnm | 1 + src/kundera-oracle-nosql/lucene/_b5.frq | 4 + src/kundera-oracle-nosql/lucene/_b5.nrm | 1 + src/kundera-oracle-nosql/lucene/_b5.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_b5.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_b5.tis | Bin 0 -> 2959 bytes src/kundera-oracle-nosql/lucene/_b7.fdt | Bin 0 -> 8092 bytes src/kundera-oracle-nosql/lucene/_b7.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_b7.fnm | 1 + src/kundera-oracle-nosql/lucene/_b7.frq | 4 + src/kundera-oracle-nosql/lucene/_b7.nrm | 1 + src/kundera-oracle-nosql/lucene/_b7.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_b7.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_b7.tis | Bin 0 -> 2959 bytes src/kundera-oracle-nosql/lucene/_b9.fdt | Bin 0 -> 8092 bytes src/kundera-oracle-nosql/lucene/_b9.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_b9.fnm | 1 + src/kundera-oracle-nosql/lucene/_b9.frq | 4 + src/kundera-oracle-nosql/lucene/_b9.nrm | 1 + src/kundera-oracle-nosql/lucene/_b9.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_b9.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_b9.tis | Bin 0 -> 2959 bytes src/kundera-oracle-nosql/lucene/_bb.fdt | Bin 0 -> 8092 bytes src/kundera-oracle-nosql/lucene/_bb.fdx | Bin 0 -> 204 bytes src/kundera-oracle-nosql/lucene/_bb.fnm | 1 + src/kundera-oracle-nosql/lucene/_bb.frq | 4 + src/kundera-oracle-nosql/lucene/_bb.nrm | 1 + src/kundera-oracle-nosql/lucene/_bb.prx | Bin 0 -> 312 bytes src/kundera-oracle-nosql/lucene/_bb.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_bb.tis | Bin 0 -> 2959 bytes src/kundera-oracle-nosql/lucene/_bd.fdt | Bin 0 -> 8306 bytes src/kundera-oracle-nosql/lucene/_bd.fdx | Bin 0 -> 212 bytes src/kundera-oracle-nosql/lucene/_bd.fnm | 1 + src/kundera-oracle-nosql/lucene/_bd.frq | 4 + src/kundera-oracle-nosql/lucene/_bd.nrm | 1 + src/kundera-oracle-nosql/lucene/_bd.prx | Bin 0 -> 322 bytes src/kundera-oracle-nosql/lucene/_bd.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_bd.tis | Bin 0 -> 3107 bytes src/kundera-oracle-nosql/lucene/_bf.fdt | Bin 0 -> 8520 bytes src/kundera-oracle-nosql/lucene/_bf.fdx | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_bf.fnm | 1 + src/kundera-oracle-nosql/lucene/_bf.frq | 4 + src/kundera-oracle-nosql/lucene/_bf.nrm | 1 + src/kundera-oracle-nosql/lucene/_bf.prx | Bin 0 -> 332 bytes src/kundera-oracle-nosql/lucene/_bf.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_bf.tis | Bin 0 -> 3151 bytes src/kundera-oracle-nosql/lucene/_bh.fdt | Bin 0 -> 8734 bytes src/kundera-oracle-nosql/lucene/_bh.fdx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_bh.fnm | 1 + src/kundera-oracle-nosql/lucene/_bh.frq | 4 + src/kundera-oracle-nosql/lucene/_bh.nrm | 1 + src/kundera-oracle-nosql/lucene/_bh.prx | Bin 0 -> 342 bytes src/kundera-oracle-nosql/lucene/_bh.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bh.tis | Bin 0 -> 3191 bytes src/kundera-oracle-nosql/lucene/_bj.fdt | Bin 0 -> 8948 bytes src/kundera-oracle-nosql/lucene/_bj.fdx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_bj.fnm | 1 + src/kundera-oracle-nosql/lucene/_bj.frq | 4 + src/kundera-oracle-nosql/lucene/_bj.nrm | 1 + src/kundera-oracle-nosql/lucene/_bj.prx | Bin 0 -> 352 bytes src/kundera-oracle-nosql/lucene/_bj.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bj.tis | Bin 0 -> 3231 bytes src/kundera-oracle-nosql/lucene/_bl.fdt | Bin 0 -> 8306 bytes src/kundera-oracle-nosql/lucene/_bl.fdx | Bin 0 -> 212 bytes src/kundera-oracle-nosql/lucene/_bl.fnm | 1 + src/kundera-oracle-nosql/lucene/_bl.frq | 4 + src/kundera-oracle-nosql/lucene/_bl.nrm | 1 + src/kundera-oracle-nosql/lucene/_bl.prx | Bin 0 -> 322 bytes src/kundera-oracle-nosql/lucene/_bl.tii | Bin 0 -> 52 bytes src/kundera-oracle-nosql/lucene/_bl.tis | Bin 0 -> 3107 bytes src/kundera-oracle-nosql/lucene/_bn.fdt | Bin 0 -> 8520 bytes src/kundera-oracle-nosql/lucene/_bn.fdx | Bin 0 -> 220 bytes src/kundera-oracle-nosql/lucene/_bn.fnm | 1 + src/kundera-oracle-nosql/lucene/_bn.frq | 4 + src/kundera-oracle-nosql/lucene/_bn.nrm | 1 + src/kundera-oracle-nosql/lucene/_bn.prx | Bin 0 -> 332 bytes src/kundera-oracle-nosql/lucene/_bn.tii | Bin 0 -> 49 bytes src/kundera-oracle-nosql/lucene/_bn.tis | Bin 0 -> 3151 bytes src/kundera-oracle-nosql/lucene/_bp.fdt | Bin 0 -> 8734 bytes src/kundera-oracle-nosql/lucene/_bp.fdx | Bin 0 -> 228 bytes src/kundera-oracle-nosql/lucene/_bp.fnm | 1 + src/kundera-oracle-nosql/lucene/_bp.frq | 4 + src/kundera-oracle-nosql/lucene/_bp.nrm | 1 + src/kundera-oracle-nosql/lucene/_bp.prx | Bin 0 -> 342 bytes src/kundera-oracle-nosql/lucene/_bp.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bp.tis | Bin 0 -> 3191 bytes src/kundera-oracle-nosql/lucene/_br.fdt | Bin 0 -> 8948 bytes src/kundera-oracle-nosql/lucene/_br.fdx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_br.fnm | 1 + src/kundera-oracle-nosql/lucene/_br.frq | 4 + src/kundera-oracle-nosql/lucene/_br.nrm | 1 + src/kundera-oracle-nosql/lucene/_br.prx | Bin 0 -> 352 bytes src/kundera-oracle-nosql/lucene/_br.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_br.tis | Bin 0 -> 3231 bytes src/kundera-oracle-nosql/lucene/_bt.fdt | Bin 0 -> 8950 bytes src/kundera-oracle-nosql/lucene/_bt.fdx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_bt.fnm | 1 + src/kundera-oracle-nosql/lucene/_bt.frq | 4 + src/kundera-oracle-nosql/lucene/_bt.nrm | 1 + src/kundera-oracle-nosql/lucene/_bt.prx | Bin 0 -> 352 bytes src/kundera-oracle-nosql/lucene/_bt.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bt.tis | Bin 0 -> 3233 bytes src/kundera-oracle-nosql/lucene/_bv.fdt | Bin 0 -> 8952 bytes src/kundera-oracle-nosql/lucene/_bv.fdx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_bv.fnm | 1 + src/kundera-oracle-nosql/lucene/_bv.frq | 4 + src/kundera-oracle-nosql/lucene/_bv.nrm | 1 + src/kundera-oracle-nosql/lucene/_bv.prx | Bin 0 -> 352 bytes src/kundera-oracle-nosql/lucene/_bv.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bv.tis | Bin 0 -> 3235 bytes src/kundera-oracle-nosql/lucene/_bx.fdt | Bin 0 -> 8954 bytes src/kundera-oracle-nosql/lucene/_bx.fdx | Bin 0 -> 236 bytes src/kundera-oracle-nosql/lucene/_bx.fnm | 1 + src/kundera-oracle-nosql/lucene/_bx.frq | 4 + src/kundera-oracle-nosql/lucene/_bx.nrm | 1 + src/kundera-oracle-nosql/lucene/_bx.prx | Bin 0 -> 352 bytes src/kundera-oracle-nosql/lucene/_bx.tii | Bin 0 -> 47 bytes src/kundera-oracle-nosql/lucene/_bx.tis | Bin 0 -> 3237 bytes src/kundera-oracle-nosql/lucene/_bx_4.del | Bin 0 -> 34 bytes src/kundera-oracle-nosql/lucene/_d.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_d.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_d.fnm | 2 + src/kundera-oracle-nosql/lucene/_d.frq | 1 + src/kundera-oracle-nosql/lucene/_d.nrm | 1 + src/kundera-oracle-nosql/lucene/_d.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_d.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_d.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_f.fdt | Bin 0 -> 862 bytes src/kundera-oracle-nosql/lucene/_f.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_f.fnm | 2 + src/kundera-oracle-nosql/lucene/_f.frq | 1 + src/kundera-oracle-nosql/lucene/_f.nrm | 1 + src/kundera-oracle-nosql/lucene/_f.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_f.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_f.tis | Bin 0 -> 347 bytes src/kundera-oracle-nosql/lucene/_h.fdt | Bin 0 -> 864 bytes src/kundera-oracle-nosql/lucene/_h.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_h.fnm | 2 + src/kundera-oracle-nosql/lucene/_h.frq | 1 + src/kundera-oracle-nosql/lucene/_h.nrm | 1 + src/kundera-oracle-nosql/lucene/_h.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_h.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_h.tis | Bin 0 -> 349 bytes src/kundera-oracle-nosql/lucene/_j.fdt | Bin 0 -> 866 bytes src/kundera-oracle-nosql/lucene/_j.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_j.fnm | 2 + src/kundera-oracle-nosql/lucene/_j.frq | 1 + src/kundera-oracle-nosql/lucene/_j.nrm | 1 + src/kundera-oracle-nosql/lucene/_j.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_j.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_j.tis | Bin 0 -> 351 bytes src/kundera-oracle-nosql/lucene/_l.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_l.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_l.fnm | 2 + src/kundera-oracle-nosql/lucene/_l.frq | 1 + src/kundera-oracle-nosql/lucene/_l.nrm | 1 + src/kundera-oracle-nosql/lucene/_l.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_l.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_l.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_n.fdt | Bin 0 -> 432 bytes src/kundera-oracle-nosql/lucene/_n.fdx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_n.fnm | 2 + src/kundera-oracle-nosql/lucene/_n.frq | 1 + src/kundera-oracle-nosql/lucene/_n.nrm | 1 + src/kundera-oracle-nosql/lucene/_n.prx | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/_n.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_n.tis | Bin 0 -> 259 bytes src/kundera-oracle-nosql/lucene/_p.fdt | Bin 0 -> 646 bytes src/kundera-oracle-nosql/lucene/_p.fdx | Bin 0 -> 28 bytes src/kundera-oracle-nosql/lucene/_p.fnm | 2 + src/kundera-oracle-nosql/lucene/_p.frq | 1 + src/kundera-oracle-nosql/lucene/_p.nrm | 1 + src/kundera-oracle-nosql/lucene/_p.prx | Bin 0 -> 30 bytes src/kundera-oracle-nosql/lucene/_p.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_p.tis | Bin 0 -> 302 bytes src/kundera-oracle-nosql/lucene/_q.fdt | Bin 0 -> 218 bytes src/kundera-oracle-nosql/lucene/_q.fdx | Bin 0 -> 12 bytes src/kundera-oracle-nosql/lucene/_q.fnm | 2 + src/kundera-oracle-nosql/lucene/_q.frq | 1 + src/kundera-oracle-nosql/lucene/_q.nrm | 1 + src/kundera-oracle-nosql/lucene/_q.prx | Bin 0 -> 10 bytes src/kundera-oracle-nosql/lucene/_q.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_q.tis | Bin 0 -> 214 bytes src/kundera-oracle-nosql/lucene/_r.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_r.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_r.fnm | 2 + src/kundera-oracle-nosql/lucene/_r.frq | 1 + src/kundera-oracle-nosql/lucene/_r.nrm | 1 + src/kundera-oracle-nosql/lucene/_r.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_r.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_r.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_t.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_t.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_t.fnm | 2 + src/kundera-oracle-nosql/lucene/_t.frq | 1 + src/kundera-oracle-nosql/lucene/_t.nrm | 1 + src/kundera-oracle-nosql/lucene/_t.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_t.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_t.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_v.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_v.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_v.fnm | 2 + src/kundera-oracle-nosql/lucene/_v.frq | 1 + src/kundera-oracle-nosql/lucene/_v.nrm | 1 + src/kundera-oracle-nosql/lucene/_v.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_v.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_v.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_x.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_x.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_x.fnm | 2 + src/kundera-oracle-nosql/lucene/_x.frq | 1 + src/kundera-oracle-nosql/lucene/_x.nrm | 1 + src/kundera-oracle-nosql/lucene/_x.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_x.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_x.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/_z.fdt | Bin 0 -> 860 bytes src/kundera-oracle-nosql/lucene/_z.fdx | Bin 0 -> 36 bytes src/kundera-oracle-nosql/lucene/_z.fnm | 2 + src/kundera-oracle-nosql/lucene/_z.frq | 1 + src/kundera-oracle-nosql/lucene/_z.nrm | 1 + src/kundera-oracle-nosql/lucene/_z.prx | Bin 0 -> 40 bytes src/kundera-oracle-nosql/lucene/_z.tii | Bin 0 -> 35 bytes src/kundera-oracle-nosql/lucene/_z.tis | Bin 0 -> 345 bytes src/kundera-oracle-nosql/lucene/segments.gen | Bin 0 -> 20 bytes src/kundera-oracle-nosql/lucene/segments_1 | Bin 0 -> 253 bytes src/kundera-oracle-nosql/lucene/segments_10 | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_12 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_14 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_16 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1b | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_1c | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_1d | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1f | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1k | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_1l | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1m | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1n | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1p | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_1y | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_1z | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2 | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_21 | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_22 | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_23 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_24 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_25 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_27 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_29 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2g | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_2h | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2j | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2p | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2r | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2t | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2v | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2x | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_2y | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_2z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3 | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_33 | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_34 | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_35 | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_37 | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_38 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_39 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3f | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_3g | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_3h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3j | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3l | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3m | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3n | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3p | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3v | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3x | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_3z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4 | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_41 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4a | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_4b | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_4c | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4d | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4g | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4p | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_4q | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_4r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4s | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_4y | Bin 0 -> 254 bytes src/kundera-oracle-nosql/lucene/segments_4z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_50 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_52 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_53 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_54 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_56 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_58 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5a | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5c | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5g | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5l | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5m | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5o | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5q | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5s | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5u | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5w | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5y | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_5z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_60 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_62 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_63 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_64 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_66 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_68 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6a | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6c | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6d | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6g | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6m | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6o | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6p | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6q | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6v | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6w | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6y | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_6z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_71 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_73 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_74 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_75 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_76 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_77 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_79 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7a | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7d | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7f | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7j | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7l | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7n | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7o | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7p | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7v | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7w | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7x | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7y | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_7z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_80 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_82 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_83 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_84 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_86 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_88 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8a | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8c | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8g | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8i | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8l | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8m | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8o | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8q | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8s | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8u | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8v | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8w | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8y | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_8z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9 | Bin 0 -> 253 bytes src/kundera-oracle-nosql/lucene/segments_90 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_92 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_94 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_95 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_97 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_99 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9b | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9d | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9e | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9g | Bin 0 -> 512 bytes src/kundera-oracle-nosql/lucene/segments_9h | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9j | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9k | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9m | Bin 0 -> 512 bytes src/kundera-oracle-nosql/lucene/segments_9n | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9o | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9p | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9r | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9t | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9u | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9w | Bin 0 -> 512 bytes src/kundera-oracle-nosql/lucene/segments_9x | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_9z | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_a | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_a0 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_a2 | Bin 0 -> 512 bytes src/kundera-oracle-nosql/lucene/segments_a3 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_a4 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_a6 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_a8 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_aa | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ab | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ac | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ae | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ag | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ai | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_aj | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ak | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_am | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ao | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_aq | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ar | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_as | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_au | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_aw | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ay | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_az | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_b1 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b3 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b5 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b7 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b8 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_b9 | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_ba | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bb | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bg | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bh | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bi | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bj | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bl | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bn | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bp | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_bu | Bin 0 -> 290 bytes src/kundera-oracle-nosql/lucene/segments_c | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_e | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_g | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_i | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_n | Bin 0 -> 32 bytes src/kundera-oracle-nosql/lucene/segments_o | Bin 0 -> 253 bytes src/kundera-oracle-nosql/lucene/segments_p | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_q | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_r | Bin 0 -> 510 bytes src/kundera-oracle-nosql/lucene/segments_s | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_u | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_w | Bin 0 -> 289 bytes src/kundera-oracle-nosql/lucene/segments_y | Bin 0 -> 289 bytes src/kundera-oracle-nosql/pom.xml | 122 + .../oraclenosql/OracleNOSQLConstants.java | 45 + .../client/oraclenosql/OracleNoSQLClient.java | 1036 +++++++++ .../oraclenosql/OracleNoSQLClientFactory.java | 170 ++ .../oraclenosql/OracleNoSQLDataHandler.java | 178 ++ .../oraclenosql/OracleNoSQLEntityReader.java | 55 + .../config/OracleNoSQLClientProperties.java | 84 + .../config/OracleNoSQLPropertyReader.java | 118 + .../index/OracleNoSQLInvertedIndexer.java | 349 +++ .../oraclenosql/query/OracleNoSQLQuery.java | 199 ++ .../query/OracleNoSQLQueryInterpreter.java | 132 ++ .../OracleEntityTransactionTest.java | 339 +++ .../OracleNoSQLAssociationTest.java | 198 ++ .../OracleNoSQLClientFactoryTest.java | 120 + .../oraclenosql/OracleNoSQLClientTest.java | 131 ++ .../OracleNoSQLEmbeddableTest.java | 370 +++ .../oraclenosql/OracleNoSQLLOBTest.java | 78 + .../OracleNoSQLMinorKeyAllDataTypeTest.java | 205 ++ .../OracleNoSQLSingleEntityTest.java | 385 ++++ .../oraclenosql/OracleNoSQLTestBase.java | 174 ++ .../batch/AddressBatchOracleNosql.java | 78 + .../OracleNosqlBatchProcessorMixedTest.java | 144 ++ .../batch/OracleNosqlBatchProcessorTest.java | 153 ++ .../batch/PersonBatchOracleNosql.java | 128 ++ .../batch/PersonBatchOracleNosqlEntity.java | 127 ++ .../StudentOracleNoSQLBigDecimal.java | 75 + .../StudentOracleNoSQLBigInteger.java | 75 + .../StudentOracleNoSQLBooleanPrimitive.java | 72 + .../StudentOracleNoSQLBooleanWrapper.java | 72 + .../StudentOracleNoSQLBytePrimitive.java | 73 + .../StudentOracleNoSQLByteWrapper.java | 73 + .../entities/StudentOracleNoSQLCalendar.java | 75 + .../entities/StudentOracleNoSQLChar.java | 73 + .../entities/StudentOracleNoSQLCharacter.java | 72 + .../entities/StudentOracleNoSQLDate.java | 75 + .../StudentOracleNoSQLDoublePrimitive.java | 73 + .../StudentOracleNoSQLDoubleWrapper.java | 73 + .../StudentOracleNoSQLFloatPrimitive.java | 72 + .../StudentOracleNoSQLFloatWrapper.java | 73 + .../entities/StudentOracleNoSQLInt.java | 73 + .../entities/StudentOracleNoSQLInteger.java | 72 + .../StudentOracleNoSQLLongPrimitive.java | 73 + .../StudentOracleNoSQLLongWrapper.java | 73 + .../StudentOracleNoSQLShortPrimitive.java | 73 + .../StudentOracleNoSQLShortWrapper.java | 73 + .../entities/StudentOracleNoSQLSqlDate.java | 75 + .../entities/StudentOracleNoSQLString.java | 73 + .../entities/StudentOracleNoSQLTime.java | 75 + .../entities/StudentOracleNoSQLTimestamp.java | 75 + .../entities/StudentOracleNoSQLUUID.java | 75 + .../datatypes/tests/OracleNoSQLBase.java | 39 + .../StudentOracleNoSQLBigDecimalTest.java | 539 +++++ .../StudentOracleNoSQLBigIntegerTest.java | 543 +++++ ...tudentOracleNoSQLBooleanPrimitiveTest.java | 515 +++++ .../StudentOracleNoSQLBooleanWrapperTest.java | 516 +++++ .../StudentOracleNoSQLBytePrimitiveTest.java | 540 +++++ .../StudentOracleNoSQLByteWrapperTest.java | 543 +++++ .../tests/StudentOracleNoSQLCharTest.java | 540 +++++ .../StudentOracleNoSQLCharacterTest.java | 548 +++++ .../tests/StudentOracleNoSQLDateTest.java | 541 +++++ ...StudentOracleNoSQLDoublePrimitiveTest.java | 541 +++++ .../StudentOracleNoSQLDoubleWrapperTest.java | 541 +++++ .../StudentOracleNoSQLFloatPrimitiveTest.java | 544 +++++ .../StudentOracleNoSQLFloatWrapperTest.java | 541 +++++ .../tests/StudentOracleNoSQLIntTest.java | 539 +++++ .../tests/StudentOracleNoSQLIntegerTest.java | 540 +++++ .../StudentOracleNoSQLLongPrimitiveTest.java | 538 +++++ .../StudentOracleNoSQLLongWrapperTest.java | 539 +++++ .../StudentOracleNoSQLShortPrimitiveTest.java | 540 +++++ .../StudentOracleNoSQLShortWrapperTest.java | 538 +++++ .../tests/StudentOracleNoSQLSqlDateTest.java | 541 +++++ .../tests/StudentOracleNoSQLStringTest.java | 533 +++++ .../tests/StudentOracleNoSQLTimeTest.java | 541 +++++ .../StudentOracleNoSQLTimestampTest.java | 548 +++++ .../tests/StudentOracleNoSQLUUIDTest.java | 554 +++++ .../entities/AddressOTOOracleNoSQL.java | 71 + .../client/oraclenosql/entities/Office.java | 105 + .../entities/PersonEmbeddedKVStore.java | 138 ++ .../oraclenosql/entities/PersonKVStore.java | 113 + .../entities/PersonOTOOracleNoSQL.java | 143 ++ .../PersonOracleNoSQLAllDataType.java | 498 ++++ .../oraclenosql/entities/UserProfile.java | 112 + .../test/resources/META-INF/persistence.xml | 67 + .../src/test/resources/nature.jpg | Bin 0 -> 1852277 bytes src/kundera-rdbms/pom.xml | 112 + .../impetus/client/rdbms/HibernateClient.java | 765 +++++++ .../impetus/client/rdbms/HibernateUtils.java | 53 + .../client/rdbms/RDBMSClientFactory.java | 145 ++ .../client/rdbms/RDBMSPropertyReader.java | 108 + .../client/rdbms/query/RDBMSEntityReader.java | 526 +++++ .../client/rdbms/query/RDBMSQuery.java | 194 ++ .../com/impetus/client/crud/BaseTest.java | 296 +++ .../com/impetus/client/crud/PersonRDBMS.java | 104 + .../impetus/client/crud/PersonRdbmsTest.java | 171 ++ .../com/impetus/client/crud/RDBMSCli.java | 244 ++ .../client/crud/datatypes/StudentBase.java | 351 +++ .../crud/datatypes/StudentEntityDef.java | 264 +++ .../client/crud/datatypes/StudentRdbms.java | 663 ++++++ .../crud/datatypes/StudentRdbmsTest.java | 188 ++ .../crud/generatedId/AddressGeneratedId.java | 60 + .../crud/generatedId/GeneratedIdTest.java | 134 ++ .../crud/generatedId/UserGeneratedId.java | 78 + .../test/resources/META-INF/persistence.xml | 53 + .../src/test/resources/hibernate.properties | 7 + .../src/test/resources/log4j.properties | 15 + src/kundera-redis/pom.xml | 94 + .../com/impetus/client/redis/RedisClient.java | 1873 +++++++++++++++ .../client/redis/RedisClientFactory.java | 375 +++ .../client/redis/RedisEntityReader.java | 64 + .../client/redis/RedisPropertyReader.java | 142 ++ .../com/impetus/client/redis/RedisQuery.java | 266 +++ .../client/redis/RedisQueryInterpreter.java | 186 ++ .../client/redis/RedisTransaction.java | 143 ++ .../impetus/client/RedisAssociationTest.java | 75 + .../client/RedisClientFactoryTest.java | 125 + .../com/impetus/client/RedisClientTest.java | 283 +++ .../impetus/client/RedisCompositeKeyTest.java | 77 + .../impetus/client/RedisEmbeddableTest.java | 95 + .../com/impetus/client/RedisQueryTest.java | 272 +++ .../impetus/client/RedisTransactionTest.java | 307 +++ .../client/entities/AddressOTORedis.java | 45 + .../com/impetus/client/entities/Month.java | 6 + .../client/entities/PersonOTORedis.java | 136 ++ .../impetus/client/entities/PersonRedis.java | 138 ++ .../client/entities/RedisCompoundKey.java | 81 + .../client/entities/RedisEmbeddedUser.java | 144 ++ .../client/entities/RedisPrimeUser.java | 94 + .../generatedId/RedisGeneratedIdTest.java | 228 ++ .../entites/RedisGeneratedIdDefault.java | 53 + .../entites/RedisGeneratedIdStrategyAuto.java | 57 + .../RedisGeneratedIdStrategyIdentity.java | 56 + .../RedisGeneratedIdStrategySequence.java | 57 + .../RedisGeneratedIdStrategyTable.java | 59 + ...isGeneratedIdWithOutSequenceGenerator.java | 56 + ...RedisGeneratedIdWithOutTableGenerator.java | 56 + ...RedisGeneratedIdWithSequenceGenerator.java | 56 + .../RedisGeneratedIdWithTableGenerator.java | 57 + .../test/resources/META-INF/persistence.xml | 28 + .../src/test/resources/RedisTest.xml | 17 + src/kundera-rest/pom.xml | 158 ++ .../kundera/rest/common/Constants.java | 56 + .../kundera/rest/common/EntityUtils.java | 167 ++ .../kundera/rest/common/JAXBUtils.java | 127 ++ .../impetus/kundera/rest/common/Response.java | 50 + .../kundera/rest/common/StreamUtils.java | 67 + .../kundera/rest/common/TokenUtils.java | 47 + .../rest/converters/CollectionConverter.java | 131 ++ .../converters/ListMessageBodyProvider.java | 70 + .../impetus/kundera/rest/dto/QueryResult.java | 54 + .../com/impetus/kundera/rest/dto/Schema.java | 79 + .../kundera/rest/dto/SchemaMetadata.java | 61 + .../com/impetus/kundera/rest/dto/Table.java | 67 + .../rest/repository/EMFRepository.java | 102 + .../kundera/rest/repository/EMRepository.java | 104 + .../rest/resources/ApplicationResource.java | 101 + .../kundera/rest/resources/CRUDResource.java | 243 ++ .../rest/resources/JPAQueryResource.java | 357 +++ .../rest/resources/MetadataResource.java | 113 + .../rest/resources/NativeQueryResource.java | 275 +++ .../rest/resources/SessionResource.java | 145 ++ .../rest/resources/TransactionResource.java | 151 ++ .../src/main/resources/log4j.properties | 15 + .../com/impetus/kundera/rest/common/Book.java | 104 + .../kundera/rest/common/CassandraCli.java | 307 +++ .../kundera/rest/common/EntityUtilsTest.java | 92 + .../kundera/rest/common/HabitatUni1ToM.java | 56 + .../kundera/rest/common/JAXBUtilsTest.java | 102 + .../kundera/rest/common/PersonnelUni1ToM.java | 75 + .../kundera/rest/common/Professional.java | 462 ++++ .../kundera/rest/common/StreamUtilsTest.java | 68 + .../kundera/rest/common/TokenUtilsTest.java | 63 + .../converters/CollectionConverterTest.java | 94 + .../impetus/kundera/rest/dao/RESTClient.java | 75 + .../kundera/rest/dao/RESTClientImpl.java | 428 ++++ .../rest/resources/CRUDResourceTest.java | 517 +++++ .../kundera/rest/resources/DataTypeTest.java | 364 +++ .../rest/resources/MetadataResourceTest.java | 102 + .../test/resources/META-INF/persistence.xml | 22 + .../src/test/resources/WEB-INF/web.xml | 37 + .../src/test/resources/cassandra.yaml | 644 ++++++ src/kundera-tests/pom.xml | 580 +++++ .../kundera/benchmark/ReadCSVFile.java | 139 ++ .../impetus/kundera/benchmark/TestResult.java | 120 + .../kundera/benchmark/WriteToExcelFile.java | 206 ++ .../tests/crossdatastore/pickr/dao/Pickr.java | 38 + .../crossdatastore/pickr/dao/PickrImpl.java | 113 + .../useraddress/dao/BaseDao.java | 90 + .../useraddress/dao/UserAddressDaoImpl.java | 148 ++ .../src/main/resources/applicationContext.xml | 14 + .../resources/kundera-cassandra.properties | 2 + .../main/resources/log4j-server.properties | 29 + .../src/main/resources/log4j.properties | 15 + .../benchmark/PerformanceTestsSuite.java | 105 + .../kundera/tests/cli/CassandraCli.java | 332 +++ .../kundera/tests/cli/CleanupUtilities.java | 64 + .../impetus/kundera/tests/cli/HBaseCli.java | 330 +++ .../generatedId/AddressMongoGeneratedId.java | 54 + .../CrossdatastoreGeneratedIdTest.java | 76 + .../generatedId/UserCassandraGeneratedId.java | 74 + .../crossdatastore/imdb/AssociationBase.java | 429 ++++ .../crossdatastore/imdb/IMDBPolyglotTest.java | 440 ++++ .../crossdatastore/imdb/TwinAssociation.java | 227 ++ .../crossdatastore/imdb/dao/BaseDao.java | 63 + .../crossdatastore/imdb/dao/IMDBDaoImpl.java | 214 ++ .../crossdatastore/imdb/entities/Actor.java | 124 + .../crossdatastore/imdb/entities/Movie.java | 141 ++ .../crossdatastore/imdb/entities/Role.java | 149 ++ .../crossdatastore/pickr/PickrBaseTest.java | 240 ++ .../pickr/PickrTestBi_1_1_1_1.java | 301 +++ .../pickr/PickrTestBi_1_1_1_1_PK.java | 306 +++ .../pickr/PickrTestBi_1_1_1_M.java | 325 +++ .../pickr/PickrTestBi_1_M_1_M.java | 365 +++ .../pickr/PickrTestBi_1_M_M_M.java | 421 ++++ .../pickr/PickrTestBi_M_1_1_M.java | 471 ++++ .../pickr/PickrTestBi_M_1_M_1.java | 614 +++++ .../pickr/PickrTestBi_M_M_1_1.java | 412 ++++ .../pickr/PickrTestBi_M_M_M_M.java | 471 ++++ .../pickr/PickrTestUni_1_1_1_1.java | 304 +++ .../pickr/PickrTestUni_1_1_1_1_PK.java | 310 +++ .../pickr/PickrTestUni_1_1_1_M.java | 336 +++ .../pickr/PickrTestUni_1_M_1_M.java | 364 +++ .../pickr/PickrTestUni_1_M_M_M.java | 366 +++ .../pickr/PickrTestUni_M_1_1_M.java | 434 ++++ .../pickr/PickrTestUni_M_1_M_1.java | 535 +++++ .../pickr/PickrTestUni_M_M_1_1.java | 423 ++++ .../pickr/PickrTestUni_M_M_M_M.java | 446 ++++ .../pickr/entities/album/AlbumBi_1_1_1_1.java | 153 ++ .../entities/album/AlbumBi_1_1_1_1_PK.java | 167 ++ .../pickr/entities/album/AlbumBi_1_1_1_M.java | 158 ++ .../pickr/entities/album/AlbumBi_1_M_1_M.java | 160 ++ .../pickr/entities/album/AlbumBi_1_M_M_M.java | 161 ++ .../pickr/entities/album/AlbumBi_M_1_1_M.java | 157 ++ .../pickr/entities/album/AlbumBi_M_1_M_1.java | 143 ++ .../pickr/entities/album/AlbumBi_M_M_1_1.java | 156 ++ .../pickr/entities/album/AlbumBi_M_M_M_M.java | 160 ++ .../entities/album/AlbumUni_1_1_1_1.java | 132 ++ .../entities/album/AlbumUni_1_1_1_1_PK.java | 146 ++ .../entities/album/AlbumUni_1_1_1_M.java | 138 ++ .../entities/album/AlbumUni_1_M_1_M.java | 139 ++ .../entities/album/AlbumUni_1_M_M_M.java | 139 ++ .../entities/album/AlbumUni_M_1_1_M.java | 138 ++ .../entities/album/AlbumUni_M_1_M_1.java | 125 + .../entities/album/AlbumUni_M_M_1_1.java | 132 ++ .../entities/album/AlbumUni_M_M_M_M.java | 139 ++ .../pickr/entities/photo/PhotoBi_1_1_1_1.java | 127 ++ .../entities/photo/PhotoBi_1_1_1_1_PK.java | 141 ++ .../pickr/entities/photo/PhotoBi_1_1_1_M.java | 131 ++ .../pickr/entities/photo/PhotoBi_1_M_1_M.java | 131 ++ .../pickr/entities/photo/PhotoBi_1_M_M_M.java | 146 ++ .../pickr/entities/photo/PhotoBi_M_1_1_M.java | 131 ++ .../pickr/entities/photo/PhotoBi_M_1_M_1.java | 124 + .../pickr/entities/photo/PhotoBi_M_M_1_1.java | 128 ++ .../pickr/entities/photo/PhotoBi_M_M_M_M.java | 132 ++ .../entities/photo/PhotoUni_1_1_1_1.java | 103 + .../entities/photo/PhotoUni_1_1_1_1_PK.java | 118 + .../entities/photo/PhotoUni_1_1_1_M.java | 106 + .../entities/photo/PhotoUni_1_M_1_M.java | 105 + .../entities/photo/PhotoUni_1_M_M_M.java | 105 + .../entities/photo/PhotoUni_M_1_1_M.java | 105 + .../entities/photo/PhotoUni_M_1_M_1.java | 105 + .../entities/photo/PhotoUni_M_M_1_1.java | 103 + .../entities/photo/PhotoUni_M_M_M_M.java | 105 + .../photographer/PhotographerBi_1_1_1_1.java | 101 + .../PhotographerBi_1_1_1_1_PK.java | 101 + .../photographer/PhotographerBi_1_1_1_M.java | 101 + .../photographer/PhotographerBi_1_M_1_M.java | 106 + .../photographer/PhotographerBi_1_M_M_M.java | 116 + .../photographer/PhotographerBi_M_1_1_M.java | 101 + .../photographer/PhotographerBi_M_1_M_1.java | 101 + .../photographer/PhotographerBi_M_M_1_1.java | 109 + .../photographer/PhotographerBi_M_M_M_M.java | 109 + .../photographer/PhotographerUni_1_1_1_1.java | 101 + .../PhotographerUni_1_1_1_1_PK.java | 101 + .../photographer/PhotographerUni_1_1_1_M.java | 94 + .../photographer/PhotographerUni_1_M_1_M.java | 109 + .../photographer/PhotographerUni_1_M_M_M.java | 118 + .../photographer/PhotographerUni_M_1_1_M.java | 101 + .../photographer/PhotographerUni_M_1_M_1.java | 101 + .../photographer/PhotographerUni_M_M_1_1.java | 109 + .../photographer/PhotographerUni_M_M_M_M.java | 109 + .../CrossDataStoreTransactionTest.java | 219 ++ .../useraddress/AssociationBase.java | 480 ++++ .../useraddress/MTMBiAssociationTest.java | 463 ++++ .../useraddress/MTMUniAssociationTest.java | 528 +++++ .../useraddress/MTOBiAssociationTest.java | 351 +++ .../useraddress/MTOUniAssociationTest.java | 394 ++++ .../useraddress/OTMBiAssociationTest.java | 375 +++ .../useraddress/OTMUniAssociationTest.java | 399 ++++ .../useraddress/OTOBiAssociationTest.java | 387 ++++ .../useraddress/OTOUniAssociationTest.java | 447 ++++ .../useraddress/TwinAssociation.java | 182 ++ .../datatype/MTMBiAssociationIntTest.java | 457 ++++ .../datatype/MTMUniAssociationIntTest.java | 563 +++++ .../datatype/MTOBiAssociationIntTest.java | 352 +++ .../datatype/MTOUniAssociationIntTest.java | 407 ++++ .../datatype/OTMBiAssociationIntTest.java | 390 ++++ .../datatype/OTMUniAssociationIntTest.java | 415 ++++ .../datatype/OTOBiAssociationIntTest.java | 379 ++++ .../datatype/OTOUniAssociationIntTest.java | 448 ++++ .../entities/HabitatBi1To1FKBigDecimal.java | 74 + .../entities/HabitatBi1ToMDouble.java | 75 + .../datatype/entities/HabitatBiMTo1Char.java | 75 + .../datatype/entities/HabitatBiMToMShort.java | 75 + .../entities/HabitatOToOFKEntityInt.java | 65 + .../entities/HabitatUni1To1FKInteger.java | 58 + .../entities/HabitatUni1ToMFloat.java | 58 + .../datatype/entities/HabitatUniMTo1Long.java | 57 + .../entities/HabitatUniMToMBigInteger.java | 60 + .../entities/PersonnelBi1To1FKInt.java | 76 + .../datatype/entities/PersonnelBi1ToMInt.java | 75 + .../datatype/entities/PersonnelBiMTo1Int.java | 75 + .../datatype/entities/PersonnelBiMToMInt.java | 79 + .../entities/PersonnelOToOFKEntityInt.java | 83 + .../entities/PersonnelUni1To1FKInt.java | 76 + .../entities/PersonnelUni1ToMInt.java | 77 + .../entities/PersonnelUniMTo1Int.java | 76 + .../entities/PersonnelUniMToMInt.java | 79 + .../useraddress/entities/HabitatBi1To1FK.java | 73 + .../useraddress/entities/HabitatBi1To1PK.java | 86 + .../useraddress/entities/HabitatBi1ToM.java | 75 + .../useraddress/entities/HabitatBiMTo1.java | 75 + .../useraddress/entities/HabitatBiMToM.java | 75 + .../entities/HabitatOToOFKEntity.java | 65 + .../entities/HabitatUni1To1FK.java | 58 + .../entities/HabitatUni1To1PK.java | 71 + .../useraddress/entities/HabitatUni1ToM.java | 58 + .../useraddress/entities/HabitatUniMTo1.java | 57 + .../useraddress/entities/HabitatUniMToM.java | 58 + .../useraddress/entities/Personnel.java | 58 + .../entities/PersonnelBi1To1FK.java | 76 + .../entities/PersonnelBi1To1PK.java | 75 + .../useraddress/entities/PersonnelBi1ToM.java | 77 + .../useraddress/entities/PersonnelBiMTo1.java | 75 + .../useraddress/entities/PersonnelBiMToM.java | 79 + .../entities/PersonnelOToOFKEntity.java | 83 + .../entities/PersonnelUni1To1FK.java | 76 + .../entities/PersonnelUni1To1PK.java | 76 + .../entities/PersonnelUni1ToM.java | 77 + .../entities/PersonnelUniMTo1.java | 76 + .../entities/PersonnelUniMToM.java | 79 + .../embeddedRDBMS/EmbeddedRDBMSUserTest.java | 398 ++++ .../tests/embeddedRDBMS/PersonalDetail.java | 139 ++ .../kundera/tests/embeddedRDBMS/Tweets.java | 112 + .../kundera/tests/embeddedRDBMS/User.java | 166 ++ .../externalproeprties/AccountHolder.java | 84 + .../tests/externalproeprties/Bank.java | 87 + .../tests/externalproeprties/BankTest.java | 111 + .../tests/file/dao/ProfilePictureDao.java | 104 + .../tests/file/dao/ProfilePictureDaoTest.java | 91 + .../tests/file/entities/ProfilePicture.java | 113 + .../persistence/jta/EjbJTAContextTest.java | 266 +++ .../jta/HabitatOToOFKEntityJTA.java | 61 + .../jta/OraclePersonnelOTOFKEntityJTA.java | 79 + .../persistence/jta/OracleToMongoJTATest.java | 187 ++ .../jta/PersonnelOToOFKEntityJTA.java | 79 + .../kundera/tests/persistence/lazy/Album.java | 104 + .../KunderaPersistenceProviderUtilTest.java | 221 ++ .../lazy/KunderaPersistenceUnitUtilTest.java | 135 ++ .../tests/persistence/lazy/LazyTestSetup.java | 199 ++ .../tests/persistence/lazy/Photographer.java | 99 + .../test/resources/META-INF/persistence.xml | 332 +++ .../resources/META-INF/persistence_2_0.xsd | 354 +++ .../src/test/resources/cassandra.yaml | 644 ++++++ .../src/test/resources/log4j.properties | 15 + src/pom.xml | 339 +++ 3534 files changed, 286765 insertions(+) create mode 100644 src/README.md create mode 100644 src/kundera-cassandra/pom.xml create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientBase.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientProperties.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraConstants.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraUtilities.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/config/CassandraPropertyReader.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandlerBase.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandlerBase.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/CassandraIndexHelper.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandlerBase.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClient.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClientFactory.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsDataHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsInvertedIndexHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsUtils.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassQuery.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassandraEntityReader.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/ResultIterator.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraSchemaManager.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraValidationClassMapper.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHost.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHostConfiguration.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraRetryService.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/CQLTranslator.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClient.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClientFactory.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataResultHelper.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftInvertedIndexHandler.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftRow.java create mode 100644 src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/TranslationException.java create mode 100644 src/kundera-cassandra/src/main/resources/log4j-server.properties create mode 100644 src/kundera-cassandra/src/main/resources/solandra.properties create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultSuperUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSchemaGenerationUsingXmlTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSuperUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUserTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressHandler.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressListenerDTO.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/CompositeTypeRunner.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonHandler.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentityTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTO.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTOTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/Phone.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PhoneId.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/ThriftClientTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUserTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CassandraBatchProcessorCQLTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CountersTestOnCql.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfiguration.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfigurationTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/OTMCRUDCQLTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/PersonCassandraCQLTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/StudentCassandraCQLTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/SuperCountersTestOnCql.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/AddressMToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/PersonMToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/BaseTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraAuthenticationTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraIdQueryTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/Employee.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/EntityTransactionTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/Group.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/MTOBiSelfAssociationTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/Month.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/MyTestEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/OTMCRUDTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAssociationTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAuth.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraLuceneTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTTLTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonLuceneCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/Token.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/TokenClient.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUserTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/UpdateDeleteJPQLLiteralTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/UserPromoCodeTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/AddressBatch.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorMixedTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatch.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatchCassandraEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPost.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPostTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CQLTranslatorTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompositeTypeTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompoundKey.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraEmbeddedAssociation.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraPrimeUser.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompositeDataTypeTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompoundKeyDataType.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/PrimeUserDataType.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/AddressOTOPK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraAddressUniOTM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserOTMTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserUniOTM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPKTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/Counters.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/CountersTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SubCounter.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCounters.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCountersTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/CassandraBase.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBase.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigDecimalTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigIntegerTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanPrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBytePrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraByteWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharacterTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDateTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoublePrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoubleWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatPrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntegerTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongPrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortPrimitiveTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortWrapperTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraSqlDateTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraStringTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimeTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimestampTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraUUIDTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigDecimal.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigInteger.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanPrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBytePrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraByteWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCalendar.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraChar.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCharacter.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDate.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoublePrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoubleWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatPrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInt.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInteger.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongPrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortPrimitive.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortWrapper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraSqlDate.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraString.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTime.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTimestamp.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraUUID.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/entity/CassandraUUIDEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/entity/PromoCode.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/entity/Users.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/CassandraGeneratedIdTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdDefault.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyAuto.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyIdentity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategySequence.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyTable.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutSequenceGenerator.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutTableGenerator.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithSequenceGenerator.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithTableGenerator.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeAddress.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfo.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfoTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/junit/TestCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraBatchEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraCli.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntitySample.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/EntityManagerFactoryImplTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryCQLV3Test.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NullableFieldAccessorTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/persistence/UpdateDeleteNamedQueryTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraPropertiesTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTMTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerValidateEntityTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaOperationTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassanrdaGeneratedIdSchemaTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Actor.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ActorTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEmbeddedPersonUniMto1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1FK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1PK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1ToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBiMTo1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1PK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1ToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUniMTo1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityHabitatUniMToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1FK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1PK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1ToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBiMTo1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1PK.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1ToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUniMto1.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonnelUniMToM.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySimple.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySuper.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraPersonalData.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Doctor.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/InvalidCounterColumnEntity.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Movie.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ValidCounterColumnFamily.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraSuperColumnDatatypeTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwitterTestBaseCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/SuperDaoCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterServiceCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ExternalLinkCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PersonalDetailCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PreferenceCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ProfessionalDetailCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/TweetCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/UserCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsCassandra.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/kundera/query/KunderaQueryTest.java create mode 100644 src/kundera-cassandra/src/test/java/com/impetus/kundera/query/ResultIteratorTest.java create mode 100644 src/kundera-cassandra/src/test/java/org/apache/cassandra/auth/SimpleAuthenticator.java create mode 100644 src/kundera-cassandra/src/test/java/org/apache/cassandra/auth/SimpleAuthority.java create mode 100644 src/kundera-cassandra/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-cassandra/src/test/resources/META-INF/persistence_2_0.xsd create mode 100644 src/kundera-cassandra/src/test/resources/access.properties create mode 100644 src/kundera-cassandra/src/test/resources/cassandra.yaml create mode 100644 src/kundera-cassandra/src/test/resources/ehcache-test.xml create mode 100644 src/kundera-cassandra/src/test/resources/kundera-cassandra.properties create mode 100644 src/kundera-cassandra/src/test/resources/kunderaConnectionTest.xml create mode 100644 src/kundera-cassandra/src/test/resources/log4j.properties create mode 100644 src/kundera-cassandra/src/test/resources/passwd.properties create mode 100644 src/kundera-core/pom.xml create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/Constants.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/DataWrapper.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/KunderaException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/KunderaPersistence.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/KunderaPersistenceProviderUtil.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/KunderaPersistenceUnitUtil.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/PersistenceProperties.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/PersistenceUtilHelper.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/annotations/Index.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/Cache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/CacheException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/CacheProvider.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/ElementCollectionCacheManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/NonOperationalCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/NonOperationalCacheProvider.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/ehcache/EhCacheProvider.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/cache/ehcache/EhCacheWrapper.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/AnnotationDiscoveryListener.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/ClassFileIterator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/ClasspathReader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/Filter.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/FilterImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/JarFileIterator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/Reader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/ResourceIterator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/classreading/ResourceReadingException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/Client.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/ClientBase.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/ClientPropertiesSetter.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/ClientResolver.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/ClientResolverException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/client/EnhanceEntity.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/AbstractPropertyReader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/AbstractSchemaConfiguration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/ClientFactoryConfiguraton.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/ClientMetadataBuilder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/ClientProperties.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/Configuration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/Configurator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/MetamodelConfiguration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfiguration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfigurationException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/PropertyReader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/SchemaConfiguration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/CollectionColumnInfo.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/ColumnInfo.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/EmbeddedColumnInfo.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/IndexInfo.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/SchemaGenerationException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/TableInfo.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/AbstractSchemaManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/SchemaManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/db/DataRow.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/db/RelationHolder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/db/SearchResult.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/generator/AutoGenerator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/generator/Generator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/generator/IdentityGenerator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/generator/SequenceGenerator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/generator/TableGenerator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/SurfaceType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Circle.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Coordinate.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Envelope.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Point.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Polygon.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Triangle.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/gis/query/GeospatialQuery.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/graph/Node.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/graph/NodeLink.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraph.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphBuilder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphUtils.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/DocumentIndexer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/Index.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/IndexCollection.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/IndexManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/Indexer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/IndexingException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexingException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneQueryUtils.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/index/lucene/Indexer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/NodeStateContext.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/DetachedState.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/ManagedState.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/NodeState.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/RemovedState.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/TransientState.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLifeCycleManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLoaderException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/CoreLoader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/GenericClientFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/KunderaAuthenticationException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/MetamodelLoaderException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceLoaderException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceXMLLoader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/KunderaMetadataManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataBuilder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataUtils.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationLoaderException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ClientMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Column.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/CoreMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EmbeddedColumn.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EntityMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/IdDiscriptor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/JoinTableMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/KunderaMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/MetamodelImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PersistenceUnitMetadata.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PropertyIndex.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Relation.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/SequenceGeneratorDiscriptor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/TableGeneratorDiscriptor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractPluralAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AttributeType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultCollectionAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultListAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultMapAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSetAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSingularAttribute.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractIdentifiableType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractManagedType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultBasicType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEmbeddableType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEntityType.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultMappedSuperClass.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/AbstractEntityFieldProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/CacheableAnnotationProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/EntityListenersProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/GeneratedValueProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/IndexProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/MetaModelBuilder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/TableProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToManyRelationMetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToOneRelationMetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToManyRelationMetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToOneRelationMetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessorFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidatorImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/InvalidEntityDefinitionException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/AbstractEntityReader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/AssociationBuilder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/Coordinator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/DefaultTransactionResource.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerFactoryImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerSession.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReader.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReaderException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/IdGenerator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaEntityTransaction.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaTransactionException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceDelegator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceValidator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/ResourceManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionBinder.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionResource.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/api/Batcher.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/CacheBase.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/ElementCollectionCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EmbeddedCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLog.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLogQueue.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/FlushManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/MainCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCacheManager.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/TransactionalCache.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/jointable/JoinTableData.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/CallbackMethod.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EntityEventDispatcher.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EventListenerException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/ExternalCallbackMethod.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/InternalCallbackMethod.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaJTAUserTransaction.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaTransaction.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/UserTransactionFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorHelper.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigDecimalAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigIntegerAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BooleanAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ByteAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CalendarAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CharAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DateAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DoubleAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/EnumAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/FloatAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/IntegerAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/LongAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ObjectAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/PointAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLDateAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLTimeAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLTimestampAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ShortAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/StringAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/UUIDAccessor.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/KunderaProxy.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/LazyInitializationException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/LazyInitializer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/LazyInitializerFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/ProxyHelper.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/cglib/CglibLazyInitializer.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/cglib/CglibLazyInitializerFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/AbstractProxyBase.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/AbstractProxyCollection.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/ProxyCollection.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/ProxyList.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/ProxyMap.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/proxy/collection/ProxySet.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/IResultIterator.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/JPQLParseException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/KunderaQuery.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/KunderaQueryParser.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/KunderaTypedQuery.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/LuceneQuery.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/Query.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/QueryHandlerException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/QueryImpl.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/query/QueryResolver.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/Host.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/HostConfiguration.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/policy/LeastActiveBalancingPolicy.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/policy/LoadBalancingPolicy.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/policy/RetryService.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/service/policy/RoundRobinBalancingPolicy.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/DeepEquals.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/InvalidConfigurationException.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/KunderaCoreUtils.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/KunderaThreadFactory.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/ObjectUtils.java create mode 100644 src/kundera-core/src/main/java/com/impetus/kundera/utils/ReflectUtils.java create mode 100644 src/kundera-core/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider create mode 100644 src/kundera-core/src/main/resources/persistence_1_0.xsd create mode 100644 src/kundera-core/src/main/resources/persistence_2_0.xsd create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/AllTestSuites.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/CoreTestUtilities.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/EntityManagerImplTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/EntityTransactionTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/KunderaPersistenceProviderUtilTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/KunderaPersistenceTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/KunderaPersistenceUnitUtilTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/PersistenceUtilHelperTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/cache/ElementCollectionCacheManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/cache/NonOperationCacheProviderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/cache/NonOperationalCacheTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/cache/ehcache/EhCacheProviderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/cache/ehcache/KunderaQueryParserTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/classreading/ClasspathReaderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/classreading/DataRowTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/classreading/FilterTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/classreading/RelationHolderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/classreading/SearchResultTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/ClientResolverTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/CoreTestClient.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/CoreTestClientFactory.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/CoreTestClientNoGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/DummyDatabase.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/DummySchema.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/DummyTable.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/client/EnhanceEntityTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/AbstractPropertyReaderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/ConfiguratorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityAddressUni1To1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityAddressUni1ToM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityAddressUniMTo1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityPersionUniMto1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityPersonUni1To1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntityPersonUni1ToM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntitySimple.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/CoreEntitySuper.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/DummyPropertyReader.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/PersonalData.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/SchemaConfigurationTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/ColumnInfoTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/EmbeddedColumnInfoTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/IndexInfoTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/TableInfoTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/api/CoreSchemaManager.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/configure/schema/api/SchemaManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/BigDecimalDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/BigIntegerDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/BooleanDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/ByteDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/CalendarDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/CharDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/DataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/DataGeneratorFactory.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/DateDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/DoubleDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/FloatDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/IntegerDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/LongDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/ShortDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/SqlDateDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/SqlTimeDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/SqlTimestampDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/StringDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/datatypes/datagenerator/UUIDDataGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/PersonalDetail.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/PersonnelDTO.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/Tweet.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumBi_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_1_1_M_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/album/AlbumUni_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoBi_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_1_1_M_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photo/PhotoUni_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerBi_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_1_1_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_1_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_1_1_M_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_1_M_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_1_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_M_1_1_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_M_M_1_1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/entity/photographer/PhotographerUni_M_M_M_M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/gis/geometry/CircleTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/gis/geometry/EnvelopeTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/gis/geometry/PointTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/gis/geometry/PolygonTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/gis/geometry/TriangleTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/graph/BillingCounter.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/graph/ObjectGraphTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/graph/ObjectGraphUtilsTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/graph/Store.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/graph/StoreBuilder.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/index/IndexManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/index/LuceneIndexerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/lifecycle/states/DetachedStateTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/lifecycle/states/ManagedStateTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/lifecycle/states/NodeStateTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/lifecycle/states/RemovedStateTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/lifecycle/states/TransientStateTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/loader/GenericClientFactoryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/KunderaMetadataManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/MetadataBuilderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/MetadataUtilsTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/AssociationEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/CollectionTypeAssociationEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/EmbeddableEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/EmbeddableEntityTwo.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/EmbeddableTransientEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/EmbeddedIdOwnerEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/IDClassEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/IDClassOwnerEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/ListTypeAssociationEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/MapTypeAssociationEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/MappedSuperClass.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/OToMOwnerEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/OToOOwnerEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/PluralOwnerType.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/RootMappedSuperClass.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SampleEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SetTypeAssociationEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SingularEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SingularEntityEmbeddable.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SubClassA.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/SubClassB.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/TransientEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/bi/AssociationBiEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/entities/bi/OToOOwnerBiEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/Department.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/Employe.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/EntityMetadataTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/KunderaUser.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/PersistenceUnitMetadataTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/ProcessAnnotationsTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/model/TweetKundera.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/AttributeTypeTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/EntitySample.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/MetaModelBuilderForTransientEntityTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/MetaModelBuilderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/TableProcessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/processor/relation/RelationProcessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/EntityValidatorImplTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/EntityWithMultipleId.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/EntityWithOutConstructor.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/EntityWithOutId.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/EntityWithOutTableAnnotation.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdDefault.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdStrategyAuto.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdStrategyIdentity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdStrategySequence.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdStrategyTable.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithInvalidGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithNoGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithOutSequenceGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithOutTableGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithSequenceGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/metadata/validator/GeneratedIdWithTableGenerator.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/AssociationBuilderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/EntityManagerSessionTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/EntityReaderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/FlushStackManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/IdGeneratorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/JPAImplementationTestSuite.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/ObjectGraphBuilderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/PersistenceCacheTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/PersistenceDelegatorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/PersistenceUnitLoaderTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/context/FlushStackTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/context/PersistenceCacheManagerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/event/AddressEntity.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/event/AddressEntityWithList.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/event/EntityEventDispatcherTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/event/PersonEventDispatch.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/event/PersonHandler.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/jta/KunderaJTAUserTransactionTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/persistence/jta/KunderaTransactionTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/dao/BaseDao.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/dao/PersonAddressDaoImpl.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressB11FK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressB11PK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressB1M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressBM1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressBMM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressU11FK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressU11PK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressU1M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressUM1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/AddressUMM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonB11FK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonB11PK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonB1M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonBM1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonBMM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonU11FK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonU11PK.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonU1M.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonUM1.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonUMM.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/entities/PersonUMMByMap.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/MMBPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/MMUPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/MOBPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/MOUPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/OMBPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/OMUPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/OOBPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/OOUPolyglotTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/polyglot/tests/PersonAddressTestBase.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/PropertyAccessorHelperTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/BigDecimalAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/BigIntegerAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/BooleanAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/ByteAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/CalendarAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/CharAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/DateAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/DoubleAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/EnumAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/FloatAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/IntegerAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/LongAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/ObjectAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/PersonalDetail.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/PointAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/SQLDateAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/SQLTimeAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/SQLTimestampAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/ShortAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/StringAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/property/accessor/UUIDAccessorTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/proxy/cglib/CglibLazyInitializerFactoryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/proxy/cglib/CglibLazyInitializerTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/proxy/collection/ProxyListTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/proxy/collection/ProxyMapTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/proxy/collection/ProxySetTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/CoreIndexer.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/CoreQuery.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/CoreTestEntityReader.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/KunderaQueryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/KunderaTypedQueryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/LuceneQueryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/Person.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/PersonTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/QueryExceptionTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/query/QueryImplTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/service/CoreHostConfiguration.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/service/HostconfigurationTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/service/policy/RoundRobinBalancingPolicyTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/DeepEqualsTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/KunderaCoreUtilsTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/KunderaThreadFactoryTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/LuceneCleanupUtilities.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/ObjectUtilsCloneBidirectionalM2MTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/ObjectUtilsCloneBidirectionalTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/ObjectUtilsCloneUnidirectionalTest.java create mode 100644 src/kundera-core/src/test/java/com/impetus/kundera/utils/ReflectUtilsTest.java create mode 100644 src/kundera-core/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-core/src/test/resources/META-INF/persistence_2_0.xsd create mode 100644 src/kundera-core/src/test/resources/ehcache-test.xml create mode 100644 src/kundera-core/src/test/resources/kunderaTest.xml create mode 100644 src/kundera-core/src/test/resources/kunderaTestDataType.xml create mode 100644 src/kundera-core/src/test/resources/log4j.properties create mode 100644 src/kundera-hbase/pom.xml create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClient.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientFactory.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientProperties.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseConstants.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseData.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseEntityReader.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/Reader.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/Writer.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/DataHandler.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/HBaseDataHandler.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/config/HBasePropertyReader.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/HBaseQuery.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/ResultIterator.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/schemamanager/HBaseSchemaManager.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseReader.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseWriter.java create mode 100644 src/kundera-hbase/src/main/java/com/impetus/client/hbase/utils/HBaseUtils.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/BookInfo.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarity.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarityTest.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPassword.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPasswordTest.java create mode 100644 src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserInfo.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseEntity.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUser.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUserTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/BaseTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseBatchProcessorTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseIdQueryTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Human.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumanTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumansPrivatePhoto.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Month.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonBatchHBaseEntity.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBaseTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/AddressOTOHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/HbaseAssociationTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/PersonOTOHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/Base.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentEntityDef.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigDecimalTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigIntegerTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanPrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBytePrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseByteWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCalendarTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharacterTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDateTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoublePrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoubleWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatPrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntegerTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongPrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortPrimitiveTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortWrapperTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseSqlDateTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseStringTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimeTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimestampTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseUUIDTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/ZkShutDownTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigDecimal.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigInteger.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanPrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBytePrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseByteWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCalendar.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseChar.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCharacter.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDate.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoublePrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoubleWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatPrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInt.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInteger.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongPrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortPrimitive.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortWrapper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseSqlDate.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseString.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTime.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTimestamp.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseUUID.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/EmbeddedEntityTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatData.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatDataId.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/HBaseGeneratedIdTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdDefault.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyAuto.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyIdentity.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategySequence.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyTable.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutSequenceGenerator.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutTableGenerator.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithSequenceGenerator.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithTableGenerator.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/junits/HBaseCli.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1PK.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1ToM.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUniMTo1.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1PK.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1ToM.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUniMto1.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySimple.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySuper.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseGeneratedIdSchemaTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBasePersonalData.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaManagerTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaOperationTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/query/ResultIteratorTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/query/Token.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/query/TokenClient.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwibaseTest.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwitterTestBaseHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/SuperDaoHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterServiceHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/ExternalLinkHBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PersonalDetailHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PreferenceHBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/TweetHbase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/UserHBase.java create mode 100644 src/kundera-hbase/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsHbase.java create mode 100644 src/kundera-hbase/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-hbase/src/test/resources/META-INF/persistence_2_0.xsd create mode 100644 src/kundera-hbase/src/test/resources/kundera-hbase.properties create mode 100644 src/kundera-hbase/src/test/resources/log4j.properties create mode 100644 src/kundera-mongo/pom.xml create mode 100644 src/kundera-mongo/src/main/java/META-INF/MANIFEST.MF create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/DocumentObjectMapper.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClient.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientFactory.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientProperties.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBConstants.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBDataHandler.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoEntityReader.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/config/MongoDBPropertyReader.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/index/IndexType.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/MongoDBQuery.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/CircleQueryImpl.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/EnvelopeQueryImpl.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/GeospatialQueryFactory.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/NearQueryImpl.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/PolygonQueryImpl.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/TriangleQueryImpl.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManager.java create mode 100644 src/kundera-mongo/src/main/java/com/impetus/client/mongodb/utils/MongoDBUtils.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/AppUser.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/BaseTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/CappedCollectionTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/CollecteTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/Day.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/EmbeddableUserTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoAuthenticationTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoBatchProcessorTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBCappedEntity.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBQueryOnIdTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonBatchMongoEntity.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongoTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/PhoneDirectory.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/UserRoleTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompositeTypeTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompoundKey.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoPrimeUser.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/MongoBase.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBase.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigDecimalTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigIntegerTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanPrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBytePrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoByteWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCalendarTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharacterTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDateTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoublePrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoubleWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatPrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntegerTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongPrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortPrimitiveTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortWrapperTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoSqlDateTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoStringTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimeTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimestampTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoUUIDTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Collecte.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Photoo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigDecimal.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigInteger.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanPrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBytePrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoByteWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCalendar.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoChar.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCharacter.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDate.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoublePrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoubleWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatPrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInt.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInteger.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongPrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortPrimitive.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortWrapper.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoSqlDate.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoString.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTime.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTimestamp.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoUUID.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/MongoGeneratedIdTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdDefault.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyAuto.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyIdentity.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategySequence.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyTable.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutSequenceGenerator.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutTableGenerator.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithSequenceGenerator.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithTableGenerator.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/gis/MongoGISTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/gis/Person.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/gis/PersonGISDao.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/gis/Vehicle.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoDBPropertyReaderTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUser.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUserTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/OperationLevelPropertiesTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/index/IndexTypeTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBEntitySimple.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManagerTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwingoTest.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwitterTestBaseMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/SuperDao.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/Twitter.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/TwitterService.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/ExternalLinkMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PersonalDetailMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PreferenceMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/RoleMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/TweetMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/User.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/UserMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsMongo.java create mode 100644 src/kundera-mongo/src/test/java/com/impetus/client/utils/MongoUtils.java create mode 100644 src/kundera-mongo/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-mongo/src/test/resources/META-INF/persistence_2_0.xsd create mode 100644 src/kundera-mongo/src/test/resources/kundera-mongo.properties create mode 100644 src/kundera-mongo/src/test/resources/kunderaMongoTest.xml create mode 100644 src/kundera-mongo/src/test/resources/log4j.properties create mode 100644 src/kundera-neo4j/pom.xml create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/GraphEntityMapper.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClient.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientBase.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientFactory.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JEntityReader.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JTransaction.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/config/Neo4JPropertyReader.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/index/Neo4JIndexManager.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JLuceneQuery.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQuery.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQueryFactory.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQuery.java create mode 100644 src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQueryType.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/GraphEntityMapperTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientFactoryTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Actor.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBBatchInsertionTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBCRUDTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBJPAQueriesTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBMapMetamodelTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBNativeLuceneQueryTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTestBase.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTransactionTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Movie.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Role.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorComposite.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorId.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/IMDBCompositeKeyTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieComposite.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieId.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleComposite.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleId.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/ActorAllDataType.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/IMDBAllDataTypeTest.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/MovieAllDataType.java create mode 100644 src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/RoleAllDataType.java create mode 100644 src/kundera-neo4j/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-neo4j/src/test/resources/kunderaNeo4JTest.xml create mode 100644 src/kundera-oracle-nosql/PROFILE_PICTURE create mode 100644 src/kundera-oracle-nosql/lucene/_0.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_0.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_0.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_0.frq create mode 100644 src/kundera-oracle-nosql/lucene/_0.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_0.prx create mode 100644 src/kundera-oracle-nosql/lucene/_0.tii create mode 100644 src/kundera-oracle-nosql/lucene/_0.tis create mode 100644 src/kundera-oracle-nosql/lucene/_11.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_11.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_11.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_11.frq create mode 100644 src/kundera-oracle-nosql/lucene/_11.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_11.prx create mode 100644 src/kundera-oracle-nosql/lucene/_11.tii create mode 100644 src/kundera-oracle-nosql/lucene/_11.tis create mode 100644 src/kundera-oracle-nosql/lucene/_13.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_13.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_13.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_13.frq create mode 100644 src/kundera-oracle-nosql/lucene/_13.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_13.prx create mode 100644 src/kundera-oracle-nosql/lucene/_13.tii create mode 100644 src/kundera-oracle-nosql/lucene/_13.tis create mode 100644 src/kundera-oracle-nosql/lucene/_15.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_15.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_15.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_15.frq create mode 100644 src/kundera-oracle-nosql/lucene/_15.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_15.prx create mode 100644 src/kundera-oracle-nosql/lucene/_15.tii create mode 100644 src/kundera-oracle-nosql/lucene/_15.tis create mode 100644 src/kundera-oracle-nosql/lucene/_17.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_17.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_17.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_17.frq create mode 100644 src/kundera-oracle-nosql/lucene/_17.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_17.prx create mode 100644 src/kundera-oracle-nosql/lucene/_17.tii create mode 100644 src/kundera-oracle-nosql/lucene/_17.tis create mode 100644 src/kundera-oracle-nosql/lucene/_19.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_19.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_19.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_19.frq create mode 100644 src/kundera-oracle-nosql/lucene/_19.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_19.prx create mode 100644 src/kundera-oracle-nosql/lucene/_19.tii create mode 100644 src/kundera-oracle-nosql/lucene/_19.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1b.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1b.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1b.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1b.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1b.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1b.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1b.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1b.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1d.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1d.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1d.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1d.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1d.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1d.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1d.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1d.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_1y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_1y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_1y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_1y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_1y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_1y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_1y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_1y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2.tis create mode 100644 src/kundera-oracle-nosql/lucene/_20.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_20.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_20.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_20.frq create mode 100644 src/kundera-oracle-nosql/lucene/_20.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_20.prx create mode 100644 src/kundera-oracle-nosql/lucene/_20.tii create mode 100644 src/kundera-oracle-nosql/lucene/_20.tis create mode 100644 src/kundera-oracle-nosql/lucene/_22.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_22.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_22.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_22.frq create mode 100644 src/kundera-oracle-nosql/lucene/_22.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_22.prx create mode 100644 src/kundera-oracle-nosql/lucene/_22.tii create mode 100644 src/kundera-oracle-nosql/lucene/_22.tis create mode 100644 src/kundera-oracle-nosql/lucene/_24.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_24.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_24.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_24.frq create mode 100644 src/kundera-oracle-nosql/lucene/_24.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_24.prx create mode 100644 src/kundera-oracle-nosql/lucene/_24.tii create mode 100644 src/kundera-oracle-nosql/lucene/_24.tis create mode 100644 src/kundera-oracle-nosql/lucene/_26.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_26.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_26.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_26.frq create mode 100644 src/kundera-oracle-nosql/lucene/_26.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_26.prx create mode 100644 src/kundera-oracle-nosql/lucene/_26.tii create mode 100644 src/kundera-oracle-nosql/lucene/_26.tis create mode 100644 src/kundera-oracle-nosql/lucene/_28.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_28.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_28.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_28.frq create mode 100644 src/kundera-oracle-nosql/lucene/_28.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_28.prx create mode 100644 src/kundera-oracle-nosql/lucene/_28.tii create mode 100644 src/kundera-oracle-nosql/lucene/_28.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2f.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2f.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2f.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2f.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2f.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2f.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2f.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2f.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2h.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2h.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2h.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2h.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2h.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2h.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2h.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2h.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2j.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2j.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2j.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2j.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2j.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2j.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2j.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2j.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2l.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2l.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2l.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2l.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2l.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2l.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2l.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2l.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2n.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2n.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2n.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2n.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2n.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2n.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2n.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2n.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2r.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2r.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2r.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2r.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2r.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2r.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2r.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2r.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2t.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2t.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2t.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2t.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2t.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2t.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2t.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2t.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2v.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2v.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2v.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2v.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2v.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2v.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2v.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2v.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2x.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2x.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2x.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2x.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2x.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2x.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2x.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2x.tis create mode 100644 src/kundera-oracle-nosql/lucene/_2z.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_2z.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_2z.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_2z.frq create mode 100644 src/kundera-oracle-nosql/lucene/_2z.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_2z.prx create mode 100644 src/kundera-oracle-nosql/lucene/_2z.tii create mode 100644 src/kundera-oracle-nosql/lucene/_2z.tis create mode 100644 src/kundera-oracle-nosql/lucene/_31.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_31.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_31.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_31.frq create mode 100644 src/kundera-oracle-nosql/lucene/_31.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_31.prx create mode 100644 src/kundera-oracle-nosql/lucene/_31.tii create mode 100644 src/kundera-oracle-nosql/lucene/_31.tis create mode 100644 src/kundera-oracle-nosql/lucene/_33.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_33.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_33.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_33.frq create mode 100644 src/kundera-oracle-nosql/lucene/_33.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_33.prx create mode 100644 src/kundera-oracle-nosql/lucene/_33.tii create mode 100644 src/kundera-oracle-nosql/lucene/_33.tis create mode 100644 src/kundera-oracle-nosql/lucene/_35.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_35.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_35.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_35.frq create mode 100644 src/kundera-oracle-nosql/lucene/_35.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_35.prx create mode 100644 src/kundera-oracle-nosql/lucene/_35.tii create mode 100644 src/kundera-oracle-nosql/lucene/_35.tis create mode 100644 src/kundera-oracle-nosql/lucene/_37.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_37.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_37.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_37.frq create mode 100644 src/kundera-oracle-nosql/lucene/_37.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_37.prx create mode 100644 src/kundera-oracle-nosql/lucene/_37.tii create mode 100644 src/kundera-oracle-nosql/lucene/_37.tis create mode 100644 src/kundera-oracle-nosql/lucene/_39.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_39.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_39.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_39.frq create mode 100644 src/kundera-oracle-nosql/lucene/_39.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_39.prx create mode 100644 src/kundera-oracle-nosql/lucene/_39.tii create mode 100644 src/kundera-oracle-nosql/lucene/_39.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3b.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3b.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3b.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3b.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3b.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3b.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3b.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3b.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3d.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3d.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3d.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3d.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3d.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3d.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3d.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3d.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3f.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3f.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3f.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3f.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3f.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3f.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3f.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3f.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3h.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3h.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3h.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3h.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3h.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3h.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3h.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3h.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3j.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3j.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3j.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3j.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3j.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3j.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3j.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3j.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3l.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3l.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3l.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3l.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3l.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3l.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3l.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3l.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3n.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3n.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3n.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3n.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3n.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3n.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3n.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3n.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3p.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3p.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3p.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3p.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3p.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3p.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3p.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3p.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3r.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3r.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3r.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3r.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3r.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3r.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3r.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3r.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3t.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3t.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3t.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3t.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3t.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3t.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3t.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3t.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3v.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3v.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3v.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3v.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3v.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3v.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3v.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3v.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3x.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3x.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3x.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3x.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3x.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3x.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3x.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3x.tis create mode 100644 src/kundera-oracle-nosql/lucene/_3z.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_3z.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_3z.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_3z.frq create mode 100644 src/kundera-oracle-nosql/lucene/_3z.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_3z.prx create mode 100644 src/kundera-oracle-nosql/lucene/_3z.tii create mode 100644 src/kundera-oracle-nosql/lucene/_3z.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4.tis create mode 100644 src/kundera-oracle-nosql/lucene/_41.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_41.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_41.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_41.frq create mode 100644 src/kundera-oracle-nosql/lucene/_41.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_41.prx create mode 100644 src/kundera-oracle-nosql/lucene/_41.tii create mode 100644 src/kundera-oracle-nosql/lucene/_41.tis create mode 100644 src/kundera-oracle-nosql/lucene/_43.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_43.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_43.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_43.frq create mode 100644 src/kundera-oracle-nosql/lucene/_43.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_43.prx create mode 100644 src/kundera-oracle-nosql/lucene/_43.tii create mode 100644 src/kundera-oracle-nosql/lucene/_43.tis create mode 100644 src/kundera-oracle-nosql/lucene/_45.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_45.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_45.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_45.frq create mode 100644 src/kundera-oracle-nosql/lucene/_45.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_45.prx create mode 100644 src/kundera-oracle-nosql/lucene/_45.tii create mode 100644 src/kundera-oracle-nosql/lucene/_45.tis create mode 100644 src/kundera-oracle-nosql/lucene/_47.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_47.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_47.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_47.frq create mode 100644 src/kundera-oracle-nosql/lucene/_47.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_47.prx create mode 100644 src/kundera-oracle-nosql/lucene/_47.tii create mode 100644 src/kundera-oracle-nosql/lucene/_47.tis create mode 100644 src/kundera-oracle-nosql/lucene/_49.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_49.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_49.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_49.frq create mode 100644 src/kundera-oracle-nosql/lucene/_49.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_49.prx create mode 100644 src/kundera-oracle-nosql/lucene/_49.tii create mode 100644 src/kundera-oracle-nosql/lucene/_49.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4b.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4b.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4b.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4b.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4b.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4b.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4b.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4b.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4d.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4d.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4d.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4d.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4d.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4d.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4d.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4d.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4i_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_4k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4q_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_4s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_4y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_4y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_4y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_4y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_4y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_4y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_4y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_4y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_50.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_50.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_50.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_50.frq create mode 100644 src/kundera-oracle-nosql/lucene/_50.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_50.prx create mode 100644 src/kundera-oracle-nosql/lucene/_50.tii create mode 100644 src/kundera-oracle-nosql/lucene/_50.tis create mode 100644 src/kundera-oracle-nosql/lucene/_52.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_52.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_52.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_52.frq create mode 100644 src/kundera-oracle-nosql/lucene/_52.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_52.prx create mode 100644 src/kundera-oracle-nosql/lucene/_52.tii create mode 100644 src/kundera-oracle-nosql/lucene/_52.tis create mode 100644 src/kundera-oracle-nosql/lucene/_52_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_54.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_54.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_54.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_54.frq create mode 100644 src/kundera-oracle-nosql/lucene/_54.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_54.prx create mode 100644 src/kundera-oracle-nosql/lucene/_54.tii create mode 100644 src/kundera-oracle-nosql/lucene/_54.tis create mode 100644 src/kundera-oracle-nosql/lucene/_56.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_56.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_56.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_56.frq create mode 100644 src/kundera-oracle-nosql/lucene/_56.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_56.prx create mode 100644 src/kundera-oracle-nosql/lucene/_56.tii create mode 100644 src/kundera-oracle-nosql/lucene/_56.tis create mode 100644 src/kundera-oracle-nosql/lucene/_58.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_58.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_58.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_58.frq create mode 100644 src/kundera-oracle-nosql/lucene/_58.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_58.prx create mode 100644 src/kundera-oracle-nosql/lucene/_58.tii create mode 100644 src/kundera-oracle-nosql/lucene/_58.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5a_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_5c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5m_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_5o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5u_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_5w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_5y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_5y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_5y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_5y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_5y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_5y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_5y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_5y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6.tis create mode 100644 src/kundera-oracle-nosql/lucene/_60.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_60.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_60.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_60.frq create mode 100644 src/kundera-oracle-nosql/lucene/_60.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_60.prx create mode 100644 src/kundera-oracle-nosql/lucene/_60.tii create mode 100644 src/kundera-oracle-nosql/lucene/_60.tis create mode 100644 src/kundera-oracle-nosql/lucene/_62.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_62.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_62.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_62.frq create mode 100644 src/kundera-oracle-nosql/lucene/_62.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_62.prx create mode 100644 src/kundera-oracle-nosql/lucene/_62.tii create mode 100644 src/kundera-oracle-nosql/lucene/_62.tis create mode 100644 src/kundera-oracle-nosql/lucene/_62_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_64.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_64.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_64.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_64.frq create mode 100644 src/kundera-oracle-nosql/lucene/_64.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_64.prx create mode 100644 src/kundera-oracle-nosql/lucene/_64.tii create mode 100644 src/kundera-oracle-nosql/lucene/_64.tis create mode 100644 src/kundera-oracle-nosql/lucene/_66.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_66.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_66.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_66.frq create mode 100644 src/kundera-oracle-nosql/lucene/_66.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_66.prx create mode 100644 src/kundera-oracle-nosql/lucene/_66.tii create mode 100644 src/kundera-oracle-nosql/lucene/_66.tis create mode 100644 src/kundera-oracle-nosql/lucene/_68.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_68.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_68.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_68.frq create mode 100644 src/kundera-oracle-nosql/lucene/_68.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_68.prx create mode 100644 src/kundera-oracle-nosql/lucene/_68.tii create mode 100644 src/kundera-oracle-nosql/lucene/_68.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6a_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_6c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6i_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_6k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6q_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_6s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_6y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_6y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_6y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_6y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_6y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_6y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_6y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_6y_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_7.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7.tis create mode 100644 src/kundera-oracle-nosql/lucene/_70.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_70.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_70.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_70.frq create mode 100644 src/kundera-oracle-nosql/lucene/_70.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_70.prx create mode 100644 src/kundera-oracle-nosql/lucene/_70.tii create mode 100644 src/kundera-oracle-nosql/lucene/_70.tis create mode 100644 src/kundera-oracle-nosql/lucene/_72.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_72.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_72.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_72.frq create mode 100644 src/kundera-oracle-nosql/lucene/_72.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_72.prx create mode 100644 src/kundera-oracle-nosql/lucene/_72.tii create mode 100644 src/kundera-oracle-nosql/lucene/_72.tis create mode 100644 src/kundera-oracle-nosql/lucene/_74.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_74.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_74.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_74.frq create mode 100644 src/kundera-oracle-nosql/lucene/_74.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_74.prx create mode 100644 src/kundera-oracle-nosql/lucene/_74.tii create mode 100644 src/kundera-oracle-nosql/lucene/_74.tis create mode 100644 src/kundera-oracle-nosql/lucene/_76.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_76.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_76.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_76.frq create mode 100644 src/kundera-oracle-nosql/lucene/_76.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_76.prx create mode 100644 src/kundera-oracle-nosql/lucene/_76.tii create mode 100644 src/kundera-oracle-nosql/lucene/_76.tis create mode 100644 src/kundera-oracle-nosql/lucene/_76_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_78.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_78.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_78.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_78.frq create mode 100644 src/kundera-oracle-nosql/lucene/_78.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_78.prx create mode 100644 src/kundera-oracle-nosql/lucene/_78.tii create mode 100644 src/kundera-oracle-nosql/lucene/_78.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7e_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_7g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7m_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_7o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_7w_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_7y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_7y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_7y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_7y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_7y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_7y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_7y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_7y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_80.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_80.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_80.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_80.frq create mode 100644 src/kundera-oracle-nosql/lucene/_80.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_80.prx create mode 100644 src/kundera-oracle-nosql/lucene/_80.tii create mode 100644 src/kundera-oracle-nosql/lucene/_80.tis create mode 100644 src/kundera-oracle-nosql/lucene/_82.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_82.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_82.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_82.frq create mode 100644 src/kundera-oracle-nosql/lucene/_82.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_82.prx create mode 100644 src/kundera-oracle-nosql/lucene/_82.tii create mode 100644 src/kundera-oracle-nosql/lucene/_82.tis create mode 100644 src/kundera-oracle-nosql/lucene/_84.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_84.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_84.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_84.frq create mode 100644 src/kundera-oracle-nosql/lucene/_84.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_84.prx create mode 100644 src/kundera-oracle-nosql/lucene/_84.tii create mode 100644 src/kundera-oracle-nosql/lucene/_84.tis create mode 100644 src/kundera-oracle-nosql/lucene/_84_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_86.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_86.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_86.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_86.frq create mode 100644 src/kundera-oracle-nosql/lucene/_86.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_86.prx create mode 100644 src/kundera-oracle-nosql/lucene/_86.tii create mode 100644 src/kundera-oracle-nosql/lucene/_86.tis create mode 100644 src/kundera-oracle-nosql/lucene/_88.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_88.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_88.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_88.frq create mode 100644 src/kundera-oracle-nosql/lucene/_88.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_88.prx create mode 100644 src/kundera-oracle-nosql/lucene/_88.tii create mode 100644 src/kundera-oracle-nosql/lucene/_88.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8g_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_8i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8o_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_8q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_8w_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_8y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_8y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_8y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_8y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_8y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_8y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_8y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_8y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9.tis create mode 100644 src/kundera-oracle-nosql/lucene/_90.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_90.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_90.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_90.frq create mode 100644 src/kundera-oracle-nosql/lucene/_90.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_90.prx create mode 100644 src/kundera-oracle-nosql/lucene/_90.tii create mode 100644 src/kundera-oracle-nosql/lucene/_90.tis create mode 100644 src/kundera-oracle-nosql/lucene/_92.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_92.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_92.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_92.frq create mode 100644 src/kundera-oracle-nosql/lucene/_92.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_92.prx create mode 100644 src/kundera-oracle-nosql/lucene/_92.tii create mode 100644 src/kundera-oracle-nosql/lucene/_92.tis create mode 100644 src/kundera-oracle-nosql/lucene/_94.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_94.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_94.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_94.frq create mode 100644 src/kundera-oracle-nosql/lucene/_94.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_94.prx create mode 100644 src/kundera-oracle-nosql/lucene/_94.tii create mode 100644 src/kundera-oracle-nosql/lucene/_94.tis create mode 100644 src/kundera-oracle-nosql/lucene/_96.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_96.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_96.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_96.frq create mode 100644 src/kundera-oracle-nosql/lucene/_96.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_96.prx create mode 100644 src/kundera-oracle-nosql/lucene/_96.tii create mode 100644 src/kundera-oracle-nosql/lucene/_96.tis create mode 100644 src/kundera-oracle-nosql/lucene/_98.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_98.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_98.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_98.frq create mode 100644 src/kundera-oracle-nosql/lucene/_98.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_98.prx create mode 100644 src/kundera-oracle-nosql/lucene/_98.tii create mode 100644 src/kundera-oracle-nosql/lucene/_98.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9a.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9a.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9a.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9a.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9a.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9a.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9a.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9a.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9c.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9c.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9c.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9c.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9c.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9c.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9c.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9c.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9e.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9e.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9e.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9e.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9e.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9e.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9e.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9e.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9g.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9g.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9g.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9g.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9g.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9g.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9g.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9g.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9g_2.del create mode 100644 src/kundera-oracle-nosql/lucene/_9h.cfs create mode 100644 src/kundera-oracle-nosql/lucene/_9i.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9i.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9i.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9i.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9i.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9i.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9i.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9i.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9k.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9k.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9k.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9k.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9k.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9k.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9k.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9k.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9m.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9m.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9m.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9m.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9m.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9m.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9m.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9m.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9m_2.del create mode 100644 src/kundera-oracle-nosql/lucene/_9n.cfs create mode 100644 src/kundera-oracle-nosql/lucene/_9o.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9o.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9o.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9o.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9o.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9o.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9o.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9o.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9s.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9s.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9s.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9s.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9s.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9s.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9s.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9s.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9u.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9u.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9u.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9u.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9u.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9u.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9u.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9u.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9w.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9w.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9w.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9w.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9w.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9w.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9w.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9w.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9y.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_9y.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_9y.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_9y.frq create mode 100644 src/kundera-oracle-nosql/lucene/_9y.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_9y.prx create mode 100644 src/kundera-oracle-nosql/lucene/_9y.tii create mode 100644 src/kundera-oracle-nosql/lucene/_9y.tis create mode 100644 src/kundera-oracle-nosql/lucene/_9y_2.del create mode 100644 src/kundera-oracle-nosql/lucene/_9z.cfs create mode 100644 src/kundera-oracle-nosql/lucene/_a0.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_a0.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_a0.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_a0.frq create mode 100644 src/kundera-oracle-nosql/lucene/_a0.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_a0.prx create mode 100644 src/kundera-oracle-nosql/lucene/_a0.tii create mode 100644 src/kundera-oracle-nosql/lucene/_a0.tis create mode 100644 src/kundera-oracle-nosql/lucene/_a2.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_a2.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_a2.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_a2.frq create mode 100644 src/kundera-oracle-nosql/lucene/_a2.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_a2.prx create mode 100644 src/kundera-oracle-nosql/lucene/_a2.tii create mode 100644 src/kundera-oracle-nosql/lucene/_a2.tis create mode 100644 src/kundera-oracle-nosql/lucene/_a4.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_a4.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_a4.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_a4.frq create mode 100644 src/kundera-oracle-nosql/lucene/_a4.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_a4.prx create mode 100644 src/kundera-oracle-nosql/lucene/_a4.tii create mode 100644 src/kundera-oracle-nosql/lucene/_a4.tis create mode 100644 src/kundera-oracle-nosql/lucene/_a4_2.del create mode 100644 src/kundera-oracle-nosql/lucene/_a5.cfs create mode 100644 src/kundera-oracle-nosql/lucene/_a6.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_a6.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_a6.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_a6.frq create mode 100644 src/kundera-oracle-nosql/lucene/_a6.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_a6.prx create mode 100644 src/kundera-oracle-nosql/lucene/_a6.tii create mode 100644 src/kundera-oracle-nosql/lucene/_a6.tis create mode 100644 src/kundera-oracle-nosql/lucene/_a8.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_a8.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_a8.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_a8.frq create mode 100644 src/kundera-oracle-nosql/lucene/_a8.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_a8.prx create mode 100644 src/kundera-oracle-nosql/lucene/_a8.tii create mode 100644 src/kundera-oracle-nosql/lucene/_a8.tis create mode 100644 src/kundera-oracle-nosql/lucene/_aa.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_aa.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_aa.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_aa.frq create mode 100644 src/kundera-oracle-nosql/lucene/_aa.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_aa.prx create mode 100644 src/kundera-oracle-nosql/lucene/_aa.tii create mode 100644 src/kundera-oracle-nosql/lucene/_aa.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ac.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ac.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ac.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ac.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ac.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ac.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ac.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ac.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ac_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_ae.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ae.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ae.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ae.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ae.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ae.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ae.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ae.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ag.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ag.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ag.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ag.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ag.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ag.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ag.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ag.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ai.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ai.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ai.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ai.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ai.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ai.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ai.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ai.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ak.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ak.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ak.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ak.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ak.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ak.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ak.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ak.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ak_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_am.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_am.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_am.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_am.frq create mode 100644 src/kundera-oracle-nosql/lucene/_am.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_am.prx create mode 100644 src/kundera-oracle-nosql/lucene/_am.tii create mode 100644 src/kundera-oracle-nosql/lucene/_am.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ao.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ao.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ao.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ao.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ao.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ao.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ao.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ao.tis create mode 100644 src/kundera-oracle-nosql/lucene/_aq.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_aq.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_aq.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_aq.frq create mode 100644 src/kundera-oracle-nosql/lucene/_aq.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_aq.prx create mode 100644 src/kundera-oracle-nosql/lucene/_aq.tii create mode 100644 src/kundera-oracle-nosql/lucene/_aq.tis create mode 100644 src/kundera-oracle-nosql/lucene/_as.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_as.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_as.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_as.frq create mode 100644 src/kundera-oracle-nosql/lucene/_as.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_as.prx create mode 100644 src/kundera-oracle-nosql/lucene/_as.tii create mode 100644 src/kundera-oracle-nosql/lucene/_as.tis create mode 100644 src/kundera-oracle-nosql/lucene/_as_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_au.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_au.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_au.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_au.frq create mode 100644 src/kundera-oracle-nosql/lucene/_au.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_au.prx create mode 100644 src/kundera-oracle-nosql/lucene/_au.tii create mode 100644 src/kundera-oracle-nosql/lucene/_au.tis create mode 100644 src/kundera-oracle-nosql/lucene/_aw.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_aw.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_aw.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_aw.frq create mode 100644 src/kundera-oracle-nosql/lucene/_aw.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_aw.prx create mode 100644 src/kundera-oracle-nosql/lucene/_aw.tii create mode 100644 src/kundera-oracle-nosql/lucene/_aw.tis create mode 100644 src/kundera-oracle-nosql/lucene/_ay.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_ay.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_ay.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_ay.frq create mode 100644 src/kundera-oracle-nosql/lucene/_ay.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_ay.prx create mode 100644 src/kundera-oracle-nosql/lucene/_ay.tii create mode 100644 src/kundera-oracle-nosql/lucene/_ay.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b0.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b0.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b0.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b0.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b0.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b0.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b0.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b0.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b0_1.del create mode 100644 src/kundera-oracle-nosql/lucene/_b3.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b3.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b3.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b3.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b3.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b3.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b3.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b3.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b5.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b5.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b5.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b5.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b5.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b5.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b5.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b5.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b7.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b7.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b7.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b7.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b7.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b7.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b7.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b7.tis create mode 100644 src/kundera-oracle-nosql/lucene/_b9.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_b9.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_b9.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_b9.frq create mode 100644 src/kundera-oracle-nosql/lucene/_b9.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_b9.prx create mode 100644 src/kundera-oracle-nosql/lucene/_b9.tii create mode 100644 src/kundera-oracle-nosql/lucene/_b9.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bb.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bb.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bb.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bb.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bb.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bb.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bb.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bb.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bd.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bd.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bd.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bd.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bd.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bd.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bd.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bd.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bf.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bf.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bf.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bf.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bf.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bf.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bf.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bf.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bh.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bh.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bh.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bh.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bh.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bh.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bh.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bh.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bj.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bj.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bj.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bj.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bj.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bj.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bj.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bj.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bl.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bl.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bl.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bl.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bl.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bl.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bl.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bl.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bn.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bn.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bn.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bn.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bn.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bn.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bn.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bn.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bp.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bp.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bp.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bp.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bp.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bp.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bp.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bp.tis create mode 100644 src/kundera-oracle-nosql/lucene/_br.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_br.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_br.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_br.frq create mode 100644 src/kundera-oracle-nosql/lucene/_br.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_br.prx create mode 100644 src/kundera-oracle-nosql/lucene/_br.tii create mode 100644 src/kundera-oracle-nosql/lucene/_br.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bt.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bt.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bt.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bt.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bt.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bt.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bt.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bt.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bv.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bv.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bv.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bv.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bv.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bv.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bv.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bv.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bx.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_bx.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_bx.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_bx.frq create mode 100644 src/kundera-oracle-nosql/lucene/_bx.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_bx.prx create mode 100644 src/kundera-oracle-nosql/lucene/_bx.tii create mode 100644 src/kundera-oracle-nosql/lucene/_bx.tis create mode 100644 src/kundera-oracle-nosql/lucene/_bx_4.del create mode 100644 src/kundera-oracle-nosql/lucene/_d.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_d.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_d.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_d.frq create mode 100644 src/kundera-oracle-nosql/lucene/_d.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_d.prx create mode 100644 src/kundera-oracle-nosql/lucene/_d.tii create mode 100644 src/kundera-oracle-nosql/lucene/_d.tis create mode 100644 src/kundera-oracle-nosql/lucene/_f.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_f.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_f.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_f.frq create mode 100644 src/kundera-oracle-nosql/lucene/_f.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_f.prx create mode 100644 src/kundera-oracle-nosql/lucene/_f.tii create mode 100644 src/kundera-oracle-nosql/lucene/_f.tis create mode 100644 src/kundera-oracle-nosql/lucene/_h.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_h.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_h.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_h.frq create mode 100644 src/kundera-oracle-nosql/lucene/_h.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_h.prx create mode 100644 src/kundera-oracle-nosql/lucene/_h.tii create mode 100644 src/kundera-oracle-nosql/lucene/_h.tis create mode 100644 src/kundera-oracle-nosql/lucene/_j.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_j.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_j.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_j.frq create mode 100644 src/kundera-oracle-nosql/lucene/_j.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_j.prx create mode 100644 src/kundera-oracle-nosql/lucene/_j.tii create mode 100644 src/kundera-oracle-nosql/lucene/_j.tis create mode 100644 src/kundera-oracle-nosql/lucene/_l.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_l.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_l.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_l.frq create mode 100644 src/kundera-oracle-nosql/lucene/_l.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_l.prx create mode 100644 src/kundera-oracle-nosql/lucene/_l.tii create mode 100644 src/kundera-oracle-nosql/lucene/_l.tis create mode 100644 src/kundera-oracle-nosql/lucene/_n.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_n.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_n.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_n.frq create mode 100644 src/kundera-oracle-nosql/lucene/_n.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_n.prx create mode 100644 src/kundera-oracle-nosql/lucene/_n.tii create mode 100644 src/kundera-oracle-nosql/lucene/_n.tis create mode 100644 src/kundera-oracle-nosql/lucene/_p.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_p.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_p.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_p.frq create mode 100644 src/kundera-oracle-nosql/lucene/_p.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_p.prx create mode 100644 src/kundera-oracle-nosql/lucene/_p.tii create mode 100644 src/kundera-oracle-nosql/lucene/_p.tis create mode 100644 src/kundera-oracle-nosql/lucene/_q.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_q.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_q.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_q.frq create mode 100644 src/kundera-oracle-nosql/lucene/_q.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_q.prx create mode 100644 src/kundera-oracle-nosql/lucene/_q.tii create mode 100644 src/kundera-oracle-nosql/lucene/_q.tis create mode 100644 src/kundera-oracle-nosql/lucene/_r.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_r.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_r.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_r.frq create mode 100644 src/kundera-oracle-nosql/lucene/_r.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_r.prx create mode 100644 src/kundera-oracle-nosql/lucene/_r.tii create mode 100644 src/kundera-oracle-nosql/lucene/_r.tis create mode 100644 src/kundera-oracle-nosql/lucene/_t.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_t.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_t.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_t.frq create mode 100644 src/kundera-oracle-nosql/lucene/_t.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_t.prx create mode 100644 src/kundera-oracle-nosql/lucene/_t.tii create mode 100644 src/kundera-oracle-nosql/lucene/_t.tis create mode 100644 src/kundera-oracle-nosql/lucene/_v.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_v.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_v.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_v.frq create mode 100644 src/kundera-oracle-nosql/lucene/_v.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_v.prx create mode 100644 src/kundera-oracle-nosql/lucene/_v.tii create mode 100644 src/kundera-oracle-nosql/lucene/_v.tis create mode 100644 src/kundera-oracle-nosql/lucene/_x.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_x.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_x.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_x.frq create mode 100644 src/kundera-oracle-nosql/lucene/_x.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_x.prx create mode 100644 src/kundera-oracle-nosql/lucene/_x.tii create mode 100644 src/kundera-oracle-nosql/lucene/_x.tis create mode 100644 src/kundera-oracle-nosql/lucene/_z.fdt create mode 100644 src/kundera-oracle-nosql/lucene/_z.fdx create mode 100644 src/kundera-oracle-nosql/lucene/_z.fnm create mode 100644 src/kundera-oracle-nosql/lucene/_z.frq create mode 100644 src/kundera-oracle-nosql/lucene/_z.nrm create mode 100644 src/kundera-oracle-nosql/lucene/_z.prx create mode 100644 src/kundera-oracle-nosql/lucene/_z.tii create mode 100644 src/kundera-oracle-nosql/lucene/_z.tis create mode 100644 src/kundera-oracle-nosql/lucene/segments.gen create mode 100644 src/kundera-oracle-nosql/lucene/segments_1 create mode 100644 src/kundera-oracle-nosql/lucene/segments_10 create mode 100644 src/kundera-oracle-nosql/lucene/segments_12 create mode 100644 src/kundera-oracle-nosql/lucene/segments_14 create mode 100644 src/kundera-oracle-nosql/lucene/segments_16 create mode 100644 src/kundera-oracle-nosql/lucene/segments_1b create mode 100644 src/kundera-oracle-nosql/lucene/segments_1c create mode 100644 src/kundera-oracle-nosql/lucene/segments_1d create mode 100644 src/kundera-oracle-nosql/lucene/segments_1e create mode 100644 src/kundera-oracle-nosql/lucene/segments_1f create mode 100644 src/kundera-oracle-nosql/lucene/segments_1k create mode 100644 src/kundera-oracle-nosql/lucene/segments_1l create mode 100644 src/kundera-oracle-nosql/lucene/segments_1m create mode 100644 src/kundera-oracle-nosql/lucene/segments_1n create mode 100644 src/kundera-oracle-nosql/lucene/segments_1p create mode 100644 src/kundera-oracle-nosql/lucene/segments_1r create mode 100644 src/kundera-oracle-nosql/lucene/segments_1t create mode 100644 src/kundera-oracle-nosql/lucene/segments_1y create mode 100644 src/kundera-oracle-nosql/lucene/segments_1z create mode 100644 src/kundera-oracle-nosql/lucene/segments_2 create mode 100644 src/kundera-oracle-nosql/lucene/segments_21 create mode 100644 src/kundera-oracle-nosql/lucene/segments_22 create mode 100644 src/kundera-oracle-nosql/lucene/segments_23 create mode 100644 src/kundera-oracle-nosql/lucene/segments_24 create mode 100644 src/kundera-oracle-nosql/lucene/segments_25 create mode 100644 src/kundera-oracle-nosql/lucene/segments_27 create mode 100644 src/kundera-oracle-nosql/lucene/segments_29 create mode 100644 src/kundera-oracle-nosql/lucene/segments_2b create mode 100644 src/kundera-oracle-nosql/lucene/segments_2g create mode 100644 src/kundera-oracle-nosql/lucene/segments_2h create mode 100644 src/kundera-oracle-nosql/lucene/segments_2i create mode 100644 src/kundera-oracle-nosql/lucene/segments_2j create mode 100644 src/kundera-oracle-nosql/lucene/segments_2k create mode 100644 src/kundera-oracle-nosql/lucene/segments_2p create mode 100644 src/kundera-oracle-nosql/lucene/segments_2r create mode 100644 src/kundera-oracle-nosql/lucene/segments_2t create mode 100644 src/kundera-oracle-nosql/lucene/segments_2v create mode 100644 src/kundera-oracle-nosql/lucene/segments_2x create mode 100644 src/kundera-oracle-nosql/lucene/segments_2y create mode 100644 src/kundera-oracle-nosql/lucene/segments_2z create mode 100644 src/kundera-oracle-nosql/lucene/segments_3 create mode 100644 src/kundera-oracle-nosql/lucene/segments_33 create mode 100644 src/kundera-oracle-nosql/lucene/segments_34 create mode 100644 src/kundera-oracle-nosql/lucene/segments_35 create mode 100644 src/kundera-oracle-nosql/lucene/segments_37 create mode 100644 src/kundera-oracle-nosql/lucene/segments_38 create mode 100644 src/kundera-oracle-nosql/lucene/segments_39 create mode 100644 src/kundera-oracle-nosql/lucene/segments_3b create mode 100644 src/kundera-oracle-nosql/lucene/segments_3f create mode 100644 src/kundera-oracle-nosql/lucene/segments_3g create mode 100644 src/kundera-oracle-nosql/lucene/segments_3h create mode 100644 src/kundera-oracle-nosql/lucene/segments_3i create mode 100644 src/kundera-oracle-nosql/lucene/segments_3j create mode 100644 src/kundera-oracle-nosql/lucene/segments_3k create mode 100644 src/kundera-oracle-nosql/lucene/segments_3l create mode 100644 src/kundera-oracle-nosql/lucene/segments_3m create mode 100644 src/kundera-oracle-nosql/lucene/segments_3n create mode 100644 src/kundera-oracle-nosql/lucene/segments_3p create mode 100644 src/kundera-oracle-nosql/lucene/segments_3r create mode 100644 src/kundera-oracle-nosql/lucene/segments_3t create mode 100644 src/kundera-oracle-nosql/lucene/segments_3v create mode 100644 src/kundera-oracle-nosql/lucene/segments_3x create mode 100644 src/kundera-oracle-nosql/lucene/segments_3z create mode 100644 src/kundera-oracle-nosql/lucene/segments_4 create mode 100644 src/kundera-oracle-nosql/lucene/segments_41 create mode 100644 src/kundera-oracle-nosql/lucene/segments_4a create mode 100644 src/kundera-oracle-nosql/lucene/segments_4b create mode 100644 src/kundera-oracle-nosql/lucene/segments_4c create mode 100644 src/kundera-oracle-nosql/lucene/segments_4d create mode 100644 src/kundera-oracle-nosql/lucene/segments_4e create mode 100644 src/kundera-oracle-nosql/lucene/segments_4g create mode 100644 src/kundera-oracle-nosql/lucene/segments_4i create mode 100644 src/kundera-oracle-nosql/lucene/segments_4k create mode 100644 src/kundera-oracle-nosql/lucene/segments_4p create mode 100644 src/kundera-oracle-nosql/lucene/segments_4q create mode 100644 src/kundera-oracle-nosql/lucene/segments_4r create mode 100644 src/kundera-oracle-nosql/lucene/segments_4s create mode 100644 src/kundera-oracle-nosql/lucene/segments_4t create mode 100644 src/kundera-oracle-nosql/lucene/segments_4y create mode 100644 src/kundera-oracle-nosql/lucene/segments_4z create mode 100644 src/kundera-oracle-nosql/lucene/segments_50 create mode 100644 src/kundera-oracle-nosql/lucene/segments_52 create mode 100644 src/kundera-oracle-nosql/lucene/segments_53 create mode 100644 src/kundera-oracle-nosql/lucene/segments_54 create mode 100644 src/kundera-oracle-nosql/lucene/segments_56 create mode 100644 src/kundera-oracle-nosql/lucene/segments_58 create mode 100644 src/kundera-oracle-nosql/lucene/segments_5a create mode 100644 src/kundera-oracle-nosql/lucene/segments_5b create mode 100644 src/kundera-oracle-nosql/lucene/segments_5c create mode 100644 src/kundera-oracle-nosql/lucene/segments_5e create mode 100644 src/kundera-oracle-nosql/lucene/segments_5g create mode 100644 src/kundera-oracle-nosql/lucene/segments_5h create mode 100644 src/kundera-oracle-nosql/lucene/segments_5i create mode 100644 src/kundera-oracle-nosql/lucene/segments_5k create mode 100644 src/kundera-oracle-nosql/lucene/segments_5l create mode 100644 src/kundera-oracle-nosql/lucene/segments_5m create mode 100644 src/kundera-oracle-nosql/lucene/segments_5o create mode 100644 src/kundera-oracle-nosql/lucene/segments_5q create mode 100644 src/kundera-oracle-nosql/lucene/segments_5s create mode 100644 src/kundera-oracle-nosql/lucene/segments_5t create mode 100644 src/kundera-oracle-nosql/lucene/segments_5u create mode 100644 src/kundera-oracle-nosql/lucene/segments_5w create mode 100644 src/kundera-oracle-nosql/lucene/segments_5y create mode 100644 src/kundera-oracle-nosql/lucene/segments_5z create mode 100644 src/kundera-oracle-nosql/lucene/segments_60 create mode 100644 src/kundera-oracle-nosql/lucene/segments_62 create mode 100644 src/kundera-oracle-nosql/lucene/segments_63 create mode 100644 src/kundera-oracle-nosql/lucene/segments_64 create mode 100644 src/kundera-oracle-nosql/lucene/segments_66 create mode 100644 src/kundera-oracle-nosql/lucene/segments_68 create mode 100644 src/kundera-oracle-nosql/lucene/segments_6a create mode 100644 src/kundera-oracle-nosql/lucene/segments_6b create mode 100644 src/kundera-oracle-nosql/lucene/segments_6c create mode 100644 src/kundera-oracle-nosql/lucene/segments_6d create mode 100644 src/kundera-oracle-nosql/lucene/segments_6e create mode 100644 src/kundera-oracle-nosql/lucene/segments_6g create mode 100644 src/kundera-oracle-nosql/lucene/segments_6h create mode 100644 src/kundera-oracle-nosql/lucene/segments_6i create mode 100644 src/kundera-oracle-nosql/lucene/segments_6k create mode 100644 src/kundera-oracle-nosql/lucene/segments_6m create mode 100644 src/kundera-oracle-nosql/lucene/segments_6o create mode 100644 src/kundera-oracle-nosql/lucene/segments_6p create mode 100644 src/kundera-oracle-nosql/lucene/segments_6q create mode 100644 src/kundera-oracle-nosql/lucene/segments_6r create mode 100644 src/kundera-oracle-nosql/lucene/segments_6t create mode 100644 src/kundera-oracle-nosql/lucene/segments_6v create mode 100644 src/kundera-oracle-nosql/lucene/segments_6w create mode 100644 src/kundera-oracle-nosql/lucene/segments_6y create mode 100644 src/kundera-oracle-nosql/lucene/segments_6z create mode 100644 src/kundera-oracle-nosql/lucene/segments_71 create mode 100644 src/kundera-oracle-nosql/lucene/segments_73 create mode 100644 src/kundera-oracle-nosql/lucene/segments_74 create mode 100644 src/kundera-oracle-nosql/lucene/segments_75 create mode 100644 src/kundera-oracle-nosql/lucene/segments_76 create mode 100644 src/kundera-oracle-nosql/lucene/segments_77 create mode 100644 src/kundera-oracle-nosql/lucene/segments_79 create mode 100644 src/kundera-oracle-nosql/lucene/segments_7a create mode 100644 src/kundera-oracle-nosql/lucene/segments_7b create mode 100644 src/kundera-oracle-nosql/lucene/segments_7d create mode 100644 src/kundera-oracle-nosql/lucene/segments_7f create mode 100644 src/kundera-oracle-nosql/lucene/segments_7h create mode 100644 src/kundera-oracle-nosql/lucene/segments_7i create mode 100644 src/kundera-oracle-nosql/lucene/segments_7j create mode 100644 src/kundera-oracle-nosql/lucene/segments_7k create mode 100644 src/kundera-oracle-nosql/lucene/segments_7l create mode 100644 src/kundera-oracle-nosql/lucene/segments_7n create mode 100644 src/kundera-oracle-nosql/lucene/segments_7o create mode 100644 src/kundera-oracle-nosql/lucene/segments_7p create mode 100644 src/kundera-oracle-nosql/lucene/segments_7r create mode 100644 src/kundera-oracle-nosql/lucene/segments_7t create mode 100644 src/kundera-oracle-nosql/lucene/segments_7v create mode 100644 src/kundera-oracle-nosql/lucene/segments_7w create mode 100644 src/kundera-oracle-nosql/lucene/segments_7x create mode 100644 src/kundera-oracle-nosql/lucene/segments_7y create mode 100644 src/kundera-oracle-nosql/lucene/segments_7z create mode 100644 src/kundera-oracle-nosql/lucene/segments_80 create mode 100644 src/kundera-oracle-nosql/lucene/segments_82 create mode 100644 src/kundera-oracle-nosql/lucene/segments_83 create mode 100644 src/kundera-oracle-nosql/lucene/segments_84 create mode 100644 src/kundera-oracle-nosql/lucene/segments_86 create mode 100644 src/kundera-oracle-nosql/lucene/segments_88 create mode 100644 src/kundera-oracle-nosql/lucene/segments_8a create mode 100644 src/kundera-oracle-nosql/lucene/segments_8b create mode 100644 src/kundera-oracle-nosql/lucene/segments_8c create mode 100644 src/kundera-oracle-nosql/lucene/segments_8e create mode 100644 src/kundera-oracle-nosql/lucene/segments_8g create mode 100644 src/kundera-oracle-nosql/lucene/segments_8h create mode 100644 src/kundera-oracle-nosql/lucene/segments_8i create mode 100644 src/kundera-oracle-nosql/lucene/segments_8k create mode 100644 src/kundera-oracle-nosql/lucene/segments_8l create mode 100644 src/kundera-oracle-nosql/lucene/segments_8m create mode 100644 src/kundera-oracle-nosql/lucene/segments_8o create mode 100644 src/kundera-oracle-nosql/lucene/segments_8q create mode 100644 src/kundera-oracle-nosql/lucene/segments_8s create mode 100644 src/kundera-oracle-nosql/lucene/segments_8t create mode 100644 src/kundera-oracle-nosql/lucene/segments_8u create mode 100644 src/kundera-oracle-nosql/lucene/segments_8v create mode 100644 src/kundera-oracle-nosql/lucene/segments_8w create mode 100644 src/kundera-oracle-nosql/lucene/segments_8y create mode 100644 src/kundera-oracle-nosql/lucene/segments_8z create mode 100644 src/kundera-oracle-nosql/lucene/segments_9 create mode 100644 src/kundera-oracle-nosql/lucene/segments_90 create mode 100644 src/kundera-oracle-nosql/lucene/segments_92 create mode 100644 src/kundera-oracle-nosql/lucene/segments_94 create mode 100644 src/kundera-oracle-nosql/lucene/segments_95 create mode 100644 src/kundera-oracle-nosql/lucene/segments_97 create mode 100644 src/kundera-oracle-nosql/lucene/segments_99 create mode 100644 src/kundera-oracle-nosql/lucene/segments_9b create mode 100644 src/kundera-oracle-nosql/lucene/segments_9d create mode 100644 src/kundera-oracle-nosql/lucene/segments_9e create mode 100644 src/kundera-oracle-nosql/lucene/segments_9g create mode 100644 src/kundera-oracle-nosql/lucene/segments_9h create mode 100644 src/kundera-oracle-nosql/lucene/segments_9j create mode 100644 src/kundera-oracle-nosql/lucene/segments_9k create mode 100644 src/kundera-oracle-nosql/lucene/segments_9m create mode 100644 src/kundera-oracle-nosql/lucene/segments_9n create mode 100644 src/kundera-oracle-nosql/lucene/segments_9o create mode 100644 src/kundera-oracle-nosql/lucene/segments_9p create mode 100644 src/kundera-oracle-nosql/lucene/segments_9r create mode 100644 src/kundera-oracle-nosql/lucene/segments_9t create mode 100644 src/kundera-oracle-nosql/lucene/segments_9u create mode 100644 src/kundera-oracle-nosql/lucene/segments_9w create mode 100644 src/kundera-oracle-nosql/lucene/segments_9x create mode 100644 src/kundera-oracle-nosql/lucene/segments_9z create mode 100644 src/kundera-oracle-nosql/lucene/segments_a create mode 100644 src/kundera-oracle-nosql/lucene/segments_a0 create mode 100644 src/kundera-oracle-nosql/lucene/segments_a2 create mode 100644 src/kundera-oracle-nosql/lucene/segments_a3 create mode 100644 src/kundera-oracle-nosql/lucene/segments_a4 create mode 100644 src/kundera-oracle-nosql/lucene/segments_a6 create mode 100644 src/kundera-oracle-nosql/lucene/segments_a8 create mode 100644 src/kundera-oracle-nosql/lucene/segments_aa create mode 100644 src/kundera-oracle-nosql/lucene/segments_ab create mode 100644 src/kundera-oracle-nosql/lucene/segments_ac create mode 100644 src/kundera-oracle-nosql/lucene/segments_ae create mode 100644 src/kundera-oracle-nosql/lucene/segments_ag create mode 100644 src/kundera-oracle-nosql/lucene/segments_ai create mode 100644 src/kundera-oracle-nosql/lucene/segments_aj create mode 100644 src/kundera-oracle-nosql/lucene/segments_ak create mode 100644 src/kundera-oracle-nosql/lucene/segments_am create mode 100644 src/kundera-oracle-nosql/lucene/segments_ao create mode 100644 src/kundera-oracle-nosql/lucene/segments_aq create mode 100644 src/kundera-oracle-nosql/lucene/segments_ar create mode 100644 src/kundera-oracle-nosql/lucene/segments_as create mode 100644 src/kundera-oracle-nosql/lucene/segments_au create mode 100644 src/kundera-oracle-nosql/lucene/segments_aw create mode 100644 src/kundera-oracle-nosql/lucene/segments_ay create mode 100644 src/kundera-oracle-nosql/lucene/segments_az create mode 100644 src/kundera-oracle-nosql/lucene/segments_b create mode 100644 src/kundera-oracle-nosql/lucene/segments_b1 create mode 100644 src/kundera-oracle-nosql/lucene/segments_b3 create mode 100644 src/kundera-oracle-nosql/lucene/segments_b5 create mode 100644 src/kundera-oracle-nosql/lucene/segments_b7 create mode 100644 src/kundera-oracle-nosql/lucene/segments_b8 create mode 100644 src/kundera-oracle-nosql/lucene/segments_b9 create mode 100644 src/kundera-oracle-nosql/lucene/segments_ba create mode 100644 src/kundera-oracle-nosql/lucene/segments_bb create mode 100644 src/kundera-oracle-nosql/lucene/segments_bg create mode 100644 src/kundera-oracle-nosql/lucene/segments_bh create mode 100644 src/kundera-oracle-nosql/lucene/segments_bi create mode 100644 src/kundera-oracle-nosql/lucene/segments_bj create mode 100644 src/kundera-oracle-nosql/lucene/segments_bl create mode 100644 src/kundera-oracle-nosql/lucene/segments_bn create mode 100644 src/kundera-oracle-nosql/lucene/segments_bp create mode 100644 src/kundera-oracle-nosql/lucene/segments_bu create mode 100644 src/kundera-oracle-nosql/lucene/segments_c create mode 100644 src/kundera-oracle-nosql/lucene/segments_e create mode 100644 src/kundera-oracle-nosql/lucene/segments_g create mode 100644 src/kundera-oracle-nosql/lucene/segments_i create mode 100644 src/kundera-oracle-nosql/lucene/segments_n create mode 100644 src/kundera-oracle-nosql/lucene/segments_o create mode 100644 src/kundera-oracle-nosql/lucene/segments_p create mode 100644 src/kundera-oracle-nosql/lucene/segments_q create mode 100644 src/kundera-oracle-nosql/lucene/segments_r create mode 100644 src/kundera-oracle-nosql/lucene/segments_s create mode 100644 src/kundera-oracle-nosql/lucene/segments_u create mode 100644 src/kundera-oracle-nosql/lucene/segments_w create mode 100644 src/kundera-oracle-nosql/lucene/segments_y create mode 100644 src/kundera-oracle-nosql/pom.xml create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/OracleNOSQLConstants.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/OracleNoSQLClient.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/OracleNoSQLClientFactory.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/OracleNoSQLDataHandler.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/OracleNoSQLEntityReader.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/config/OracleNoSQLClientProperties.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/config/OracleNoSQLPropertyReader.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/index/OracleNoSQLInvertedIndexer.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/query/OracleNoSQLQuery.java create mode 100644 src/kundera-oracle-nosql/src/main/java/com/impetus/client/oraclenosql/query/OracleNoSQLQueryInterpreter.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleEntityTransactionTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLAssociationTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLClientFactoryTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLClientTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLEmbeddableTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLLOBTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLMinorKeyAllDataTypeTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLSingleEntityTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/OracleNoSQLTestBase.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/batch/AddressBatchOracleNosql.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/batch/OracleNosqlBatchProcessorMixedTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/batch/OracleNosqlBatchProcessorTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/batch/PersonBatchOracleNosql.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/batch/PersonBatchOracleNosqlEntity.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLBigDecimal.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLBigInteger.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLBooleanPrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLBooleanWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLBytePrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLByteWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLCalendar.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLChar.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLCharacter.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLDate.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLDoublePrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLDoubleWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLFloatPrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLFloatWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLInt.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLInteger.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLLongPrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLLongWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLShortPrimitive.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLShortWrapper.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLSqlDate.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLString.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLTime.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLTimestamp.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/entities/StudentOracleNoSQLUUID.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/OracleNoSQLBase.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLBigDecimalTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLBigIntegerTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLBooleanPrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLBooleanWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLBytePrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLByteWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLCharTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLCharacterTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLDateTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLDoublePrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLDoubleWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLFloatPrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLFloatWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLIntTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLIntegerTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLLongPrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLLongWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLShortPrimitiveTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLShortWrapperTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLSqlDateTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLStringTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLTimeTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLTimestampTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/datatypes/tests/StudentOracleNoSQLUUIDTest.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/AddressOTOOracleNoSQL.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/Office.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/PersonEmbeddedKVStore.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/PersonKVStore.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/PersonOTOOracleNoSQL.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/PersonOracleNoSQLAllDataType.java create mode 100644 src/kundera-oracle-nosql/src/test/java/com/impetus/client/oraclenosql/entities/UserProfile.java create mode 100644 src/kundera-oracle-nosql/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-oracle-nosql/src/test/resources/nature.jpg create mode 100644 src/kundera-rdbms/pom.xml create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/HibernateClient.java create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/HibernateUtils.java create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/RDBMSClientFactory.java create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/RDBMSPropertyReader.java create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/query/RDBMSEntityReader.java create mode 100644 src/kundera-rdbms/src/main/java/com/impetus/client/rdbms/query/RDBMSQuery.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/BaseTest.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/PersonRDBMS.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/PersonRdbmsTest.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/RDBMSCli.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/datatypes/StudentBase.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/datatypes/StudentRdbms.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/datatypes/StudentRdbmsTest.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/generatedId/AddressGeneratedId.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/generatedId/GeneratedIdTest.java create mode 100644 src/kundera-rdbms/src/test/java/com/impetus/client/crud/generatedId/UserGeneratedId.java create mode 100644 src/kundera-rdbms/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-rdbms/src/test/resources/hibernate.properties create mode 100644 src/kundera-rdbms/src/test/resources/log4j.properties create mode 100644 src/kundera-redis/pom.xml create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisClient.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisClientFactory.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisEntityReader.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisPropertyReader.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisQuery.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisQueryInterpreter.java create mode 100644 src/kundera-redis/src/main/java/com/impetus/client/redis/RedisTransaction.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisAssociationTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisClientFactoryTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisClientTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisCompositeKeyTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisEmbeddableTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisQueryTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/RedisTransactionTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/AddressOTORedis.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/Month.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/PersonOTORedis.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/PersonRedis.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/RedisCompoundKey.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/RedisEmbeddedUser.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/entities/RedisPrimeUser.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/RedisGeneratedIdTest.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdDefault.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdStrategyAuto.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdStrategyIdentity.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdStrategySequence.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdStrategyTable.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdWithOutSequenceGenerator.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdWithOutTableGenerator.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdWithSequenceGenerator.java create mode 100644 src/kundera-redis/src/test/java/com/impetus/client/generatedId/entites/RedisGeneratedIdWithTableGenerator.java create mode 100644 src/kundera-redis/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-redis/src/test/resources/RedisTest.xml create mode 100644 src/kundera-rest/pom.xml create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/Constants.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/EntityUtils.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/JAXBUtils.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/Response.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/StreamUtils.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/common/TokenUtils.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/converters/CollectionConverter.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/converters/ListMessageBodyProvider.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/dto/QueryResult.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/dto/Schema.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/dto/SchemaMetadata.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/dto/Table.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/repository/EMFRepository.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/repository/EMRepository.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/ApplicationResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/CRUDResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/JPAQueryResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/MetadataResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/NativeQueryResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/SessionResource.java create mode 100644 src/kundera-rest/src/main/java/com/impetus/kundera/rest/resources/TransactionResource.java create mode 100644 src/kundera-rest/src/main/resources/log4j.properties create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/Book.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/CassandraCli.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/EntityUtilsTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/HabitatUni1ToM.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/JAXBUtilsTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/PersonnelUni1ToM.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/Professional.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/StreamUtilsTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/common/TokenUtilsTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/converters/CollectionConverterTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/dao/RESTClient.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/dao/RESTClientImpl.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/resources/CRUDResourceTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/resources/DataTypeTest.java create mode 100644 src/kundera-rest/src/test/java/com/impetus/kundera/rest/resources/MetadataResourceTest.java create mode 100644 src/kundera-rest/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-rest/src/test/resources/WEB-INF/web.xml create mode 100644 src/kundera-rest/src/test/resources/cassandra.yaml create mode 100644 src/kundera-tests/pom.xml create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/benchmark/ReadCSVFile.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/benchmark/TestResult.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/benchmark/WriteToExcelFile.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/tests/crossdatastore/pickr/dao/Pickr.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/tests/crossdatastore/pickr/dao/PickrImpl.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/tests/crossdatastore/useraddress/dao/BaseDao.java create mode 100644 src/kundera-tests/src/main/java/com/impetus/kundera/tests/crossdatastore/useraddress/dao/UserAddressDaoImpl.java create mode 100644 src/kundera-tests/src/main/resources/applicationContext.xml create mode 100644 src/kundera-tests/src/main/resources/kundera-cassandra.properties create mode 100644 src/kundera-tests/src/main/resources/log4j-server.properties create mode 100644 src/kundera-tests/src/main/resources/log4j.properties create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/benchmark/PerformanceTestsSuite.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/cli/CassandraCli.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/cli/CleanupUtilities.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/cli/HBaseCli.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/generatedId/AddressMongoGeneratedId.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/generatedId/CrossdatastoreGeneratedIdTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/generatedId/UserCassandraGeneratedId.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/AssociationBase.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/IMDBPolyglotTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/TwinAssociation.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/dao/BaseDao.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/dao/IMDBDaoImpl.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/entities/Actor.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/entities/Movie.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/imdb/entities/Role.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrBaseTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestBi_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/PickrTestUni_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumBi_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/album/AlbumUni_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoBi_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photo/PhotoUni_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerBi_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_1_1_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_1_1_1_1_PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_1_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_1_M_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_1_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_M_1_1_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_M_1_M_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_M_M_1_1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/pickr/entities/photographer/PhotographerUni_M_M_M_M.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/transaction/CrossDataStoreTransactionTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/AssociationBase.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/MTMBiAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/MTMUniAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/MTOBiAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/MTOUniAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/OTMBiAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/OTMUniAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/OTOBiAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/OTOUniAssociationTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/TwinAssociation.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/MTMBiAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/MTMUniAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/MTOBiAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/MTOUniAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/OTMBiAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/OTMUniAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/OTOBiAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/OTOUniAssociationIntTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatBi1To1FKBigDecimal.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatBi1ToMDouble.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatBiMTo1Char.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatBiMToMShort.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatOToOFKEntityInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatUni1To1FKInteger.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatUni1ToMFloat.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatUniMTo1Long.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/HabitatUniMToMBigInteger.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelBi1To1FKInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelBi1ToMInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelBiMTo1Int.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelBiMToMInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelOToOFKEntityInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelUni1To1FKInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelUni1ToMInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelUniMTo1Int.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/datatype/entities/PersonnelUniMToMInt.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatBi1To1FK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatBi1To1PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatBi1ToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatBiMTo1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatBiMToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatOToOFKEntity.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatUni1To1FK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatUni1To1PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatUni1ToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatUniMTo1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/HabitatUniMToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/Personnel.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelBi1To1FK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelBi1To1PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelBi1ToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelBiMTo1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelBiMToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelOToOFKEntity.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelUni1To1FK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelUni1To1PK.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelUni1ToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelUniMTo1.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/crossdatastore/useraddress/entities/PersonnelUniMToM.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/embeddedRDBMS/EmbeddedRDBMSUserTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/embeddedRDBMS/PersonalDetail.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/embeddedRDBMS/Tweets.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/embeddedRDBMS/User.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/externalproeprties/AccountHolder.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/externalproeprties/Bank.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/externalproeprties/BankTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/file/dao/ProfilePictureDao.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/file/dao/ProfilePictureDaoTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/file/entities/ProfilePicture.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/jta/EjbJTAContextTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/jta/HabitatOToOFKEntityJTA.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/jta/OraclePersonnelOTOFKEntityJTA.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/jta/OracleToMongoJTATest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/jta/PersonnelOToOFKEntityJTA.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/lazy/Album.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/lazy/KunderaPersistenceProviderUtilTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/lazy/KunderaPersistenceUnitUtilTest.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/lazy/LazyTestSetup.java create mode 100644 src/kundera-tests/src/test/java/com/impetus/kundera/tests/persistence/lazy/Photographer.java create mode 100644 src/kundera-tests/src/test/resources/META-INF/persistence.xml create mode 100644 src/kundera-tests/src/test/resources/META-INF/persistence_2_0.xsd create mode 100644 src/kundera-tests/src/test/resources/cassandra.yaml create mode 100644 src/kundera-tests/src/test/resources/log4j.properties create mode 100644 src/pom.xml diff --git a/src/README.md b/src/README.md new file mode 100644 index 000000000..7521350ef --- /dev/null +++ b/src/README.md @@ -0,0 +1,190 @@ +Overview +========= +The idea behind Kundera is to make working with NoSQL Databases drop-dead simple and fun. Kundera is being developed with following objectives: + +* To make working with NoSQL as simple as working with SQL +* To serve as JPA Compliant mapping solution for NoSQL Datastores. +* To help developers, forget the complexity of NoSQL stores and focus on Domain Model. +* To make switching across data-stores as easy as changing a configuration. + + +[Downloads] (https://github.com/impetus-opensource/Kundera/wiki/Stable-Release "Downloads") + + +Up and running in 5 minutes +============================ +If you have worked upon Hibernate or any JPA Compliant ORM Solution, then the whole process, right from learning to coming up with first sample implementation will not take more than 5 minutes. Please follow below steps from [this link] (https://github.com/impetus-opensource/Kundera/wiki/Getting-Started-in-5-minutes "Getting started in 5 minutes"): + ++ Set up Cassandra server. ++ Download and include Kundera Jar ++ Write persistence.xml file ++ Write Entity class ++ Moment of Truth! + + +Currently Supported Datasources +================================ +* Cassandra +* MongoDB +* HBase +* Redis +* OracleNoSQL +* Neo4j +* Relational databases + + +Recent Releases +================================ +####Please Note: trunk is current development branch. 2.6 is released tag. + +#### 06-July-2013 - Kundera 2.6 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.5: + +* Lazy fetching of relationships. +* Multiple node support for Cassandra. +* Pagination support for Cassandra and HBase + + +#### 30-Apr-2013 - Kundera 2.5 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.4: + +* Support for OracleNoSQL + [Please use the Oracle NoSQL jars from the Oracle NoSQL distribution at: + http://download.oracle.com/otn-pub/otn_software/nosql-database/kv-ce-2.0.26.zip. + For the convenience of those who want to build Kundera from source we have additionally + placed the jars at http://kundera.googlecode.com/svn/maven2/maven-missing-resources/] + +* CQL 3.0 interoperability with thrift + + +#### 08-Mar-2013 - Kundera 2.4 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.3: + +* Support for Neo4j graph database +* Primary key auto-generation +* Support for JoinByPrimaryKey relationship +* Custom Secondary indexing hooks +* Hadoop 0.94.3 migration + + +#### 24-Jan-2013 - Kundera 2.3 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.2: + +* Redis Support +* Cassandra 1.2 migration. +* HBase schema handling changes +* Stronger query support, like selective column/id search via JPQL. +* Enabled support for @Transient for embedded columns and mapped super class. +* Record limit setting on search for mongodb . + + +#### 08-Nov-2012 - Kundera 2.2 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.1: + +* Geospatial Persistence and Queries for MongoDB +* Composite keys support for Cassandra and MongoDB +* Cassandra 1.1.6 migration +* Support for enum data type +* Named and Native queries support for REST based access + +#### 21-Sep-2012 - Kundera 2.1 released +This release includes [bug fixes] (https://github.com/impetus-opensource/Kundera/wiki/Bug-Fixes), performance improvements and the following new features compared to version 2.0.7: + +* CQL Version configuration +* Batch insert/update for Cassandra/MongoDB/HBase +* JPA MetaModel and TypedQuery implementation +* Raw thrift client support for Cassandra +* Datastore specific XML configuration. (.properties file deprecated) +* Stronger query support: + - JPQL support over all data types and associations + - JPQL support to query using primary key alongwith other columns +* JPA compliance + - EntityManager methods implementation (contains, refresh, detach, setProperty) + - EntityManagerFactory methods (getPersistenceUnitUtil) + - Persistence methods (getProviderUtil) + + +#### 25-July-2012 - Kundera 2.0.7 released +This release includes bug fixes, performance improvements and the following new features compared to version 2.0.6: + + +* HBase 0.92.1 migration +* Hadoop 1.0.2 migration +* Cassandra 1.1.2 migration +* MongoDB 2.0.4 migration +* JPA EntityTransaction commit and rollback +* JTA Transactions integration over web server +* Kundera-REST API +* Support for Counter column in cassandra +* Inverted wide-row indexing support for Cassandra +* Login Authentication support for Cassandra and MongoDB +* Filters and filters list for HBase +* Deprecated Lucene based indexing for HBase. +* Datastore specific configuration files for specifying: + - Replication factor + - Placement strategy + - Consistency level per operation. + - Counter column family configuration + - Inverted indexing switch + - Zookeeper host and port + - Hbase column family configurations + - MongoDB servers list, read preference and socket timeout. + ...etc. + + +#### 20-Apr-2012 - Kundera 2.0.6 released +This release includes bug fixes and the following new features compared to version 2.0.5: + +* HBase 0.90.x migration. +* Enhanced Persistence Context. +* Named and Native queries support (including CQL support for cassandra) +* UPDATE and DELETE queries support. +* DDL auto-schema creation. +* Performance improvements. + +#### 06-Feb-2012 - Kundera 2.0.5 released +This release includes bug fixes and the following new features compared to version 2.0.4: + +* Cassandra 1.x migration. +* Support for Many-to-Many relationship (via Join table) +* Transitive persistence. +* Datastore native secondary index support in addition to Lucene based indexing. An optional switch provided to change between two. +* Query support for >, < , >=,<=,!=, like, order by, like, logical operators and between. +* Connection pooling settings provided for all datastores. +* Support for all data types as required by JPA. +* Range queries for cassandra (via between clause in JPA-QL) +* Bug fixes related to self join. + + +#### 09-Dec-2011 - Kundera 2.0.4 released +This release includes bug fixes, performance improvements and the following new features compared to version 2.0.3: + +* Cross-datastore persistence. +* Support for relational databases. +* Moved out solandra and replaced with lucene. + +#### 08-Aug-2011 - Kundera 2.0.3 released +This release includes bug fixes and the following new features compared to version 2.0.2: + +* Cassandra 0.8.x support added + +#### 31-July-2011 - Kundera 2.0.2 released +This release includes bug fixes and the following new features compared to version 2.0.1: + +* Kundera is now JPA 2.0 compliant. +* Embedded objects/ collections support for HBase. + +#### 12-July-2011 - Kundera 2.0.1 released +This release includes bug fixes and the following new features compared to initial revision: + +* Cassandra 0.7.x support added +* @Embedded annotation fields persisted co located with parent entity +* Search within embedded objects. +* Selective index. + +[Downloads] (https://github.com/impetus-opensource/Kundera/wiki/Stable-Release "Downloads") + + +About Us +======== +Kundera is backed by Impetus Labs - iLabs. iLabs is a R&D consulting division of Impetus Technologies (http://www.impetus.com). iLabs focuses on innovations with next generation technologies and creates practice areas and new products around them. iLabs is actively involved working on High Performance computing technologies, ranging from distributed/parallel computing, Erlang, grid softwares, GPU based software, Hadoop, Hbase, Cassandra, CouchDB and related technologies. iLabs is also working on various other Open Source initiatives. diff --git a/src/kundera-cassandra/pom.xml b/src/kundera-cassandra/pom.xml new file mode 100644 index 000000000..f55244c48 --- /dev/null +++ b/src/kundera-cassandra/pom.xml @@ -0,0 +1,201 @@ + + 4.0.0 + + + com.impetus + kundera + 2.7-SNAPSHOT + + + com.impetus.client + kundera-cassandra + jar + kundera-cassandra + http://maven.apache.org + + + + cassandra-dependency + Cassandra Dependencies + http://repo1.maven.org/maven2 + + true + + + + + + 1.2.4 + + + + + + junit + junit + 4.8.2 + test + + + + com.impetus.core + kundera-core + ${project.version} + + + com.impetus.core + kundera-core + ${project.version} + test-jar + test + + + org.apache.cassandra + cassandra-all + ${cassandra.version} + + + org.apache.cassandra + cassandra-clientutil + ${cassandra.version} + + + + + org.jboss.netty + netty + 3.2.8.Final + + + + org.slf4j + slf4j-api + 1.7.2 + + + org.slf4j + slf4j-log4j12 + 1.7.2 + + + + log4j + log4j + 1.2.16 + test + + + + org.scale7 + scale7-pelops + 1.3-1.1.x + + + org.xerial + snappy + 1.0.1-rc4 + + + + + + org.databene + contiperf + 2.2.0 + test + + + + net.dataforte.cassandra + 0.7.1 + cassandra-connection-pool + + + org.apache.cassandra + cassandra-all + + + + + + + + + + + maven-clean-plugin + 2.4.1 + + + + ${basedir} + + .git/** + .gitignore + + + lucene/** + + + + + + + + maven-assembly-plugin + 2.2.1 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + + + + + diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientBase.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientBase.java new file mode 100644 index 000000000..7af3b10a8 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientBase.java @@ -0,0 +1,1998 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra; + +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javassist.Modifier; + +import javax.persistence.PersistenceException; +import javax.persistence.Transient; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ColumnPath; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.CounterColumn; +import org.apache.cassandra.thrift.CounterSuperColumn; +import org.apache.cassandra.thrift.CqlResult; +import org.apache.cassandra.thrift.CqlRow; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KeySlice; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.SuperColumn; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.commons.lang.StringUtils; +import org.apache.thrift.TException; +import org.scale7.cassandra.pelops.Bytes; +import org.scale7.cassandra.pelops.ColumnOrSuperColumnHelper; +import org.scale7.cassandra.pelops.pool.IThriftPool.IPooledConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.schemamanager.CassandraValidationClassMapper; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.client.cassandra.thrift.CQLTranslator.TranslationType; +import com.impetus.client.cassandra.thrift.ThriftClientFactory.Connection; +import com.impetus.client.cassandra.thrift.ThriftDataResultHelper; +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.DataRow; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Base Class for all Cassandra Clients Contains methods that are applicable to + * (but not specific to) different Cassandra clients. + * + * @author amresh.singh + */ +public abstract class CassandraClientBase extends ClientBase implements ClientPropertiesSetter +{ + + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(CassandraClientBase.class); + + /** The cql version. */ + private String cqlVersion = CassandraConstants.CQL_VERSION_2_0; + + /** The consistency level. */ + private ConsistencyLevel consistencyLevel = ConsistencyLevel.ONE; + + private boolean ttlPerRequest = false; + + private boolean ttlPerSession = false; + + private Map ttlValues = new HashMap(); + + /** The closed. */ + private boolean closed = false; + + /** list of nodes for batch processing. */ + private List nodes = new ArrayList(); + + /** batch size. */ + private int batchSize; + + private Map externalProperties; + + protected CQLClient cqlClient; + + /** + * constructor using fields. + * + * @param persistenceUnit + * the persistence unit + * @param externalProperties + */ + protected CassandraClientBase(String persistenceUnit, Map externalProperties) + { + this.externalProperties = externalProperties; + this.cqlClient = new CQLClient(); + setBatchSize(persistenceUnit, this.externalProperties); + populateCqlVersion(externalProperties); + } + + /** + * Populates foreign key as column. + * + * @param rlName + * relation name + * @param rlValue + * relation value + * @param timestamp + * the timestamp + * @return the column + * @throws PropertyAccessException + * the property access exception + */ + protected Column populateFkey(String rlName, Object rlValue, long timestamp) throws PropertyAccessException + { + Column col = new Column(); + col.setName(PropertyAccessorFactory.STRING.toBytes(rlName)); + col.setValue(PropertyAccessorHelper.getBytes(rlValue)); + col.setTimestamp(timestamp); + return col; + } + + /** + * On counter column. + * + * @param m + * the m + * @param isRelation + * the is relation + * @param relations + * the relations + * @param ks + * the ks + * @return the list + */ + protected List onCounterColumn(EntityMetadata m, boolean isRelation, List relations, + List ks) + { + List entities; + + if (m.getType().isSuperColumnFamilyMetadata()) + { + if (log.isInfoEnabled()) + { + log.info("On counter column for super column family of entity {}.", m.getEntityClazz()); + } + + Map> qCounterSuperColumnResults = ColumnOrSuperColumnHelper + .transformKeySlices(ks, ColumnOrSuperColumnHelper.COUNTER_SUPER_COLUMN); + entities = new ArrayList(qCounterSuperColumnResults.size()); + + for (Bytes key : qCounterSuperColumnResults.keySet()) + { + List counterSuperColumns = qCounterSuperColumnResults.get(key); + ThriftRow tr = new ThriftRow(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), + key.toByteArray()), m.getTableName(), new ArrayList(0), new ArrayList(0), + new ArrayList(0), counterSuperColumns); + entities.add(getDataHandler().populateEntity(tr, m, relations, isRelation)); + } + + } + else + { + + if (log.isInfoEnabled()) + { + log.info("On counter column for column family of entity {}", m.getEntityClazz()); + } + + Map> qCounterColumnResults = ColumnOrSuperColumnHelper.transformKeySlices(ks, + ColumnOrSuperColumnHelper.COUNTER_COLUMN); + entities = new ArrayList(qCounterColumnResults.size()); + + for (Bytes key : qCounterColumnResults.keySet()) + { + List counterColumns = qCounterColumnResults.get(key); + ThriftRow tr = new ThriftRow(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), + key.toByteArray()), m.getTableName(), new ArrayList(0), new ArrayList(0), + counterColumns, new ArrayList(0)); + entities.add(getDataHandler().populateEntity(tr, m, relations, isRelation)); + } + } + return entities; + } + + /** + * Compute entity via columns. + * + * @param m + * the m + * @param isRelation + * the is relation + * @param relations + * the relations + * @param entities + * the entities + * @param qResults + * the q results + */ + protected void computeEntityViaColumns(EntityMetadata m, boolean isRelation, List relations, + List entities, Map> qResults) + { + for (Bytes key : qResults.keySet()) + { + List columns = qResults.get(key); + ThriftRow tr = new ThriftRow(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), + key.toByteArray()), m.getTableName(), columns, new ArrayList(0), + new ArrayList(0), new ArrayList(0)); + Object o = getDataHandler().populateEntity(tr, m, relations, isRelation); + + if (log.isInfoEnabled()) + { + log.info("Populating data for entity of clazz {} and row key {}.", m.getEntityClazz(), tr.getId()); + } + + if (o != null) + { + entities.add(o); + } + + } + } + + /** + * Compute entity via super columns. + * + * @param m + * the m + * @param isRelation + * the is relation + * @param relations + * the relations + * @param entities + * the entities + * @param qResults + * the q results + */ + protected void computeEntityViaSuperColumns(EntityMetadata m, boolean isRelation, List relations, + List entities, Map> qResults) + { + for (Bytes key : qResults.keySet()) + { + List superColumns = qResults.get(key); + + ThriftRow tr = new ThriftRow(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), + key.toByteArray()), m.getTableName(), new ArrayList(0), superColumns, + new ArrayList(0), new ArrayList(0)); + + Object o = getDataHandler().populateEntity(tr, m, relations, isRelation); + + if (log.isInfoEnabled()) + { + log.info("Populating data for super column family of clazz {} and row key {}.", m.getEntityClazz(), + tr.getId()); + } + + if (o != null) + { + entities.add(o); + } + + } + } + + /** + * Adds relation foreign key values as thrift column/ value to thrift row. + * + * @param metadata + * the metadata + * @param tf + * the tf + * @param relations + * the relations + */ + protected void addRelationsToThriftRow(EntityMetadata metadata, ThriftRow tf, List relations) + { + if (relations != null) + { + long timestamp = System.currentTimeMillis(); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + for (RelationHolder rh : relations) + { + String linkName = rh.getRelationName(); + Object linkValue = rh.getRelationValue(); + + if (linkName != null && linkValue != null) + { + if (metaModel.getEmbeddables(metadata.getEntityClazz()).isEmpty()) + { + if (metadata.isCounterColumnType()) + { + CounterColumn col = populateCounterFkey(linkName, linkValue); + tf.addCounterColumn(col); + } + else + { + Column col = populateFkey(linkName, linkValue, timestamp); + tf.addColumn(col); + } + + } + else + { + if (metadata.isCounterColumnType()) + { + CounterSuperColumn counterSuperColumn = new CounterSuperColumn(); + counterSuperColumn.setName(linkName.getBytes()); + CounterColumn column = populateCounterFkey(linkName, linkValue); + counterSuperColumn.addToColumns(column); + tf.addCounterSuperColumn(counterSuperColumn); + } + else + { + SuperColumn superColumn = new SuperColumn(); + superColumn.setName(linkName.getBytes()); + Column column = populateFkey(linkName, linkValue, timestamp); + superColumn.addToColumns(column); + tf.addSuperColumn(superColumn); + } + } + } + } + } + } + + /** + * Populate counter fkey. + * + * @param rlName + * the rl name + * @param rlValue + * the rl value + * @return the counter column + */ + private CounterColumn populateCounterFkey(String rlName, Object rlValue) + { + CounterColumn counterCol = new CounterColumn(); + counterCol.setName(PropertyAccessorFactory.STRING.toBytes(rlName)); + counterCol.setValue((Long) rlValue); + return counterCol; + } + + /** + * Deletes record for given primary key from counter column family. + * + * @param pKey + * the key + * @param metadata + * the metadata + * @param consistencyLevel + * the consistency level + */ + protected void deleteRecordFromCounterColumnFamily(Object pKey, EntityMetadata metadata, + ConsistencyLevel consistencyLevel) + { + ColumnPath path = new ColumnPath(metadata.getTableName()); + + Cassandra.Client conn = null; + Object pooledConnection = null; + try + { + pooledConnection = getConection(); + conn = getConnection(pooledConnection); + + if (log.isInfoEnabled()) + { + log.info("Removing data for counter column family {}.", metadata.getTableName()); + } + + conn.remove_counter((CassandraUtilities.toBytes(pKey, metadata.getIdAttribute().getJavaType())).getBytes(), + path, consistencyLevel); + + } + catch (Exception e) + { + log.error("Error during executing delete, Caused by: .", e); + throw new PersistenceException(e); + } + finally + { + releaseConnection(pooledConnection); + } + } + + /** + * Creates secondary indexes on columns if not already created. + * + * @param tableName + * Column family name + * @param poolName + * Pool Name + * @param columns + * List of columns + * @param columnType + */ + protected void createIndexesOnColumns(EntityMetadata m, String tableName, List columns, Class columnType) + { + Object pooledConnection = null; + try + { + Cassandra.Client api = null; + pooledConnection = getConection(); + api = getConnection(pooledConnection); + KsDef ksDef = api.describe_keyspace(m.getSchema()); + List cfDefs = ksDef.getCf_defs(); + + // Column family definition on which secondary index creation is + // required + CfDef columnFamilyDefToUpdate = null; + boolean isUpdatable = false; + // boolean isNew=false; + + for (CfDef cfDef : cfDefs) + { + if (cfDef.getName().equals(tableName)) + { + columnFamilyDefToUpdate = cfDef; + // isNew=false; + break; + } + } + + if (columnFamilyDefToUpdate == null) + { + log.error("Join table {} not available.", tableName); + throw new PersistenceException("table" + tableName + " not found!"); + } + // create a column family, in case it is not already available. + + // Get list of indexes already created + List columnMetadataList = columnFamilyDefToUpdate.getColumn_metadata(); + List indexList = new ArrayList(); + + if (columnMetadataList != null) + { + for (ColumnDef columnDef : columnMetadataList) + { + indexList.add(Bytes.toUTF8(columnDef.getName())); + } + // need to set them to null else it is giving problem on update + // column family and trying to add again existing indexes. + // columnFamilyDefToUpdate.column_metadata = null; + } + + // Iterate over all columns for creating secondary index on them + for (Column column : columns) + { + + ColumnDef columnDef = new ColumnDef(); + + columnDef.setName(column.getName()); + columnDef.setValidation_class(CassandraValidationClassMapper.getValidationClass(columnType, false)); + columnDef.setIndex_type(IndexType.KEYS); + + // Add secondary index only if it's not already created + // (if already created, it would be there in column family + // definition) + if (!indexList.contains(Bytes.toUTF8(column.getName()))) + { + isUpdatable = true; + columnFamilyDefToUpdate.addToColumn_metadata(columnDef); + } + } + + // Finally, update column family with modified column family + // definition + if (isUpdatable) + { + columnFamilyDefToUpdate.setKey_validation_class(CassandraValidationClassMapper.getValidationClass(m + .getIdAttribute().getJavaType(), isCql3Enabled(m))); + api.system_update_column_family(columnFamilyDefToUpdate); + } + + } + catch (Exception e) + { + log.warn("Could not create secondary index on column family {}, Caused by: . ", tableName, e); + + } + finally + { + releaseConnection(pooledConnection); + } + } + + /** + * Finds an entiry from database. + * + * @param entityClass + * the entity class + * @param rowId + * the row id + * @return the object + */ + public Object find(Class entityClass, Object rowId) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + List relationNames = entityMetadata.getRelationNames(); + return find(entityClass, entityMetadata, rowId, relationNames); + } + + /** + * Finds a {@link List} of entities from database. + * + * @param + * the element type + * @param entityClass + * the entity class + * @param columnsToSelect + * TODO + * @param rowIds + * the row ids + * @return the list + */ + public List findAll(Class entityClass, String[] columnsToSelect, Object... rowIds) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + List results = new ArrayList(); + results = find(entityClass, entityMetadata.getRelationNames(), entityMetadata.getRelationNames() != null + && !entityMetadata.getRelationNames().isEmpty(), entityMetadata, rowIds); + return results.isEmpty() ? null : results; + } + + /** + * Find. + * + * @param clazz + * the clazz + * @param metadata + * the metadata + * @param rowId + * the row id + * @param relationNames + * the relation names + * @return the object + */ + private final Object find(Class clazz, EntityMetadata metadata, Object rowId, List relationNames) + { + + List result = null; + try + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + if (isCql3Enabled(metadata)) + { + result = cqlClient.find(metaModel, metadata, rowId, relationNames); + } + else + { + result = (List) find(clazz, relationNames, relationNames != null, metadata, rowId); + } + } + catch (Exception e) + { + log.error("Error while retrieving records from database for entity {} and key {}, Caused by: .", clazz, + rowId, e); + + throw new PersistenceException(e); + } + + return result != null && !result.isEmpty() ? result.get(0) : null; + } + + /** + * Returns true in case of, composite Id and if cql3 opted and not a + * embedded entity. + * + * @param metadata + * @param metaModel + * @return + */ + public boolean isCql3Enabled(EntityMetadata metadata) + { + if (metadata != null) + { + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + + if (metaModel.isEmbeddable(metadata.getIdAttribute().getBindableJavaType())) + { + return true; + } + else if (getCqlVersion().equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0) + && metadata.getType().equals(Type.SUPER_COLUMN_FAMILY)) + { + log.warn("Super Columns not supported by cql, Any operation on supercolumn family will be executed using thrift, returning false."); + return false; + } + return getCqlVersion().equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0); + } + return getCqlVersion().equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0); + } + + /** + * Returns true in case of, composite Id and if cql3 opted and not a + * embedded entity. + * + * @param metadata + * @param metaModel + * @return + */ + private boolean isCql3Enabled() + { + return isCql3Enabled(null); + } + + /** + * Find. + * + * @param + * the element type + * @param entityClass + * the entity class + * @param superColumnMap + * the super column map + * @param dataHandler + * the data handler + * @return the list + */ + public List find(Class entityClass, Map superColumnMap, CassandraDataHandler dataHandler) + { + List entities = null; + String entityId = null; + try + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(getPersistenceUnit(), entityClass); + entities = new ArrayList(); + for (String superColumnName : superColumnMap.keySet()) + { + entityId = superColumnMap.get(superColumnName); + List superColumnList = loadSuperColumns(entityMetadata.getSchema(), + entityMetadata.getTableName(), entityId, + new String[] { superColumnName.substring(0, superColumnName.indexOf("|")) }); + E e = (E) dataHandler.fromThriftRow(entityMetadata.getEntityClazz(), entityMetadata, + new DataRow(entityId, entityMetadata.getTableName(), superColumnList)); + if (e != null) + { + entities.add(e); + } + } + } + catch (Exception e) + { + log.error("Error while retrieving records from database for entity {} and key {}, Caused by: . ", + entityClass, entityId, e); + throw new KunderaException(e); + } + return entities; + } + + /** + * Executes Query. + * + * @param cqlQuery + * the cql query + * @param clazz + * the clazz + * @param relationalField + * the relational field + * @param dataHandler + * the data handler + * @return the list + */ + public List executeQuery(String cqlQuery, Class clazz, List relationalField, + CassandraDataHandler dataHandler) + { + if (log.isInfoEnabled()) + { + log.info("Executing cql query {}.", cqlQuery); + } + return cqlClient.executeQuery(cqlQuery, clazz, relationalField, dataHandler, false); + } + + public Map getExternalProperties() + { + return externalProperties; + } + + /** + * Populate data. + * + * @param m + * the m + * @param qResults + * the q results + * @param entities + * the entities + * @param isRelational + * the is relational + * @param relationNames + * the relation names + * @param dataHandler + * the data handler + */ + protected void populateData(EntityMetadata m, Map> qResults, List entities, + boolean isRelational, List relationNames, CassandraDataHandler dataHandler) + { + if (m.getType().isSuperColumnFamilyMetadata()) + { + Set primaryKeys = qResults.keySet(); + + if (primaryKeys != null && !primaryKeys.isEmpty()) + { + Object[] rowIds = new Object[primaryKeys.size()]; + int i = 0; + for (Bytes b : primaryKeys) + { + rowIds[i] = PropertyAccessorHelper.getObject(b, (Field) m.getIdAttribute().getJavaMember()); + i++; + } + entities.addAll(findAll(m.getEntityClazz(), null, rowIds)); + } + + } + else + { + Iterator rowIter = qResults.keySet().iterator(); + while (rowIter.hasNext()) + { + Bytes rowKey = rowIter.next(); + List columns = qResults.get(rowKey); + try + { + Object id = PropertyAccessorHelper + .getObject(m.getIdAttribute().getJavaType(), rowKey.toByteArray()); + + Object e = dataHandler.populateEntity(new ThriftRow(id, m.getTableName(), columns, + new ArrayList(0), new ArrayList(0), + new ArrayList(0)), m, relationNames, isRelational); + if (e != null) + { + entities.add(e); + } + } + catch (IllegalStateException e) + { + log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e); + throw new KunderaException(e); + } + catch (Exception e) + { + log.error("Error while returning entities for {}, Caused by: .", m.getEntityClazz(), e); + throw new KunderaException(e); + } + } + } + + } + + /** + * Populate entities from key slices. + * + * @param m + * the m + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param keys + * the keys + * @param dataHandler + * the data handler + * @return the list + * @throws Exception + * the exception + */ + protected List populateEntitiesFromKeySlices(EntityMetadata m, boolean isWrapReq, List relations, + List keys, CassandraDataHandler dataHandler) throws Exception + { + List results; + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + // List superColumnNames = m.getEmbeddedColumnFieldNames(); + Set superColumnAttribs = metaModel.getEmbeddables(m.getEntityClazz()).keySet(); + results = new ArrayList(keys.size()); + + ThriftDataResultHelper dataGenerator = new ThriftDataResultHelper(); + for (KeySlice key : keys) + { + List columns = key.getColumns(); + + byte[] rowKey = key.getKey(); + + Object id = PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), rowKey); + Map> data = new HashMap>(1); + data.put(ByteBuffer.wrap(rowKey), columns); + ThriftRow tr = new ThriftRow(); + tr.setId(id); + tr.setColumnFamilyName(m.getTableName()); + tr = dataGenerator.translateToThriftRow(data, m.isCounterColumnType(), m.getType(), tr); + results.add(dataHandler.populateEntity(tr, m, relations, isWrapReq)); + } + return results; + } + + /** + * Return insert query string for given entity. + * + * @param entityMetadata + * @param entity + * @param cassandra_client + * @param rlHolders + * @param ttlColumns + * TTL values for each columns + * @return + */ + protected String createInsertQuery(EntityMetadata entityMetadata, Object entity, Cassandra.Client cassandra_client, + List rlHolders, Object ttlColumns) + { + CQLTranslator translator = new CQLTranslator(); + String insert_Query = translator.INSERT_QUERY; + + insert_Query = StringUtils.replace(insert_Query, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), entityMetadata.getTableName()).toString()); + HashMap translation = translator.prepareColumnOrColumnValues(entity, entityMetadata, + TranslationType.ALL, externalProperties); + + String columnNames = translation.get(TranslationType.COLUMN); + String columnValues = translation.get(TranslationType.VALUE); + StringBuilder columnNameBuilder = new StringBuilder(columnNames); + StringBuilder columnValueBuilder = new StringBuilder(columnValues); + + for (RelationHolder rl : rlHolders) + { + columnNameBuilder.append(","); + columnValueBuilder.append(","); + translator.appendColumnName(columnNameBuilder, rl.getRelationName()); + translator.appendValue(columnValueBuilder, rl.getRelationValue().getClass(), rl.getRelationValue(), true); + } + + translation.put(TranslationType.COLUMN, columnNameBuilder.toString()); + translation.put(TranslationType.VALUE, columnValueBuilder.toString()); + + insert_Query = StringUtils.replace(insert_Query, CQLTranslator.COLUMN_VALUES, + translation.get(TranslationType.VALUE)); + insert_Query = StringUtils + .replace(insert_Query, CQLTranslator.COLUMNS, translation.get(TranslationType.COLUMN)); + + if (log.isInfoEnabled()) + { + log.info("Returning cql query {}.", insert_Query); + } + + if (ttlColumns != null && ttlColumns instanceof Integer) + { + int ttl = ((Integer) ttlColumns).intValue(); + if (ttl != 0) + { + insert_Query = insert_Query + " USING TTL " + ttl; + } + } + return insert_Query; + } + + /** + * Return update query string for given entity intended for counter column + * family. + * + * @param entityMetadata + * @param entity + * @param cassandra_client + * @param rlHolders + * @return + */ + protected String createUpdateQueryForCounter(EntityMetadata entityMetadata, Object entity, + Cassandra.Client cassandra_client, List rlHolders) + { + CQLTranslator translator = new CQLTranslator(); + String update_Query = translator.UPDATE_QUERY; + + update_Query = StringUtils.replace(update_Query, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), entityMetadata.getTableName()).toString()); + StringBuilder builder = new StringBuilder(update_Query); + builder.append(CQLTranslator.ADD_SET_CLAUSE); + + Object rowId = PropertyAccessorHelper.getId(entity, entityMetadata); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(entityMetadata.getEntityClazz()); + + Set attributes = entityType.getAttributes(); + + for (Attribute attrib : attributes) + { + if (!entityMetadata.getIdAttribute().getName().equals(attrib.getName()) + && !metaModel.isEmbeddable(attrib.getJavaType()) && !attrib.isAssociation()) + { + translator.buildSetClauseForCounters(builder, ((AbstractAttribute) attrib).getJPAColumnName(), + PropertyAccessorHelper.getObject(entity, attrib.getName())); + } + } + for (RelationHolder rl : rlHolders) + { + translator.buildSetClauseForCounters(builder, rl.getRelationName(), rl.getRelationValue()); + } + + // strip last "," clause. + builder.delete(builder.lastIndexOf(CQLTranslator.COMMA_STR), builder.length()); + onWhereClause(entityMetadata, rowId, translator, builder, metaModel); + + if (log.isInfoEnabled()) + { + log.info("Returning update query {}.", builder.toString()); + } + return builder.toString(); + } + + /** + * Gets the cql version. + * + * @return the cqlVersion + */ + protected String getCqlVersion() + { + return cqlVersion; + } + + /** + * Sets the cql version. + * + * @param cqlVersion + * the cqlVersion to set + */ + public void setCqlVersion(String cqlVersion) + { + this.cqlVersion = cqlVersion; + } + + /** + * Sets the consistency level. + * + * @param cLevel + * the new consistency level + */ + public void setConsistencyLevel(ConsistencyLevel cLevel) + { + if (cLevel != null) + { + this.consistencyLevel = cLevel; + } + else + { + log.warn("Invalid consistency level {null} provided, default level will be used."); + } + } + + /** + * Close. + */ + public void close() + { + clear(); + setCqlVersion(CassandraConstants.CQL_VERSION_2_0); + closed = true; + externalProperties = null; + } + + /** + * Checks if is open. + * + * @return true, if is open + */ + protected final boolean isOpen() + { + return !closed; + } + + /** + * Gets the consistency level. + * + * @return the consistency level + */ + protected ConsistencyLevel getConsistencyLevel() + { + return consistencyLevel; + } + + /** + * On delete query. + * + * @param metadata + * the metadata + * @param metaModel + * the meta model + * @param keyObject + * the compound key object + * @param compoundKey + * the compound key + */ + protected String onDeleteQuery(EntityMetadata metadata, MetamodelImpl metaModel, Object keyObject) + { + CQLTranslator translator = new CQLTranslator(); + String deleteQuery = CQLTranslator.DELETE_QUERY; + + deleteQuery = StringUtils.replace(deleteQuery, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), metadata.getTableName()).toString()); + + StringBuilder deleteQueryBuilder = new StringBuilder(deleteQuery); + onWhereClause(metadata, keyObject, translator, deleteQueryBuilder, metaModel); + + if (log.isInfoEnabled()) + { + log.info("Returning delete query {}.", deleteQueryBuilder.toString()); + } + return deleteQueryBuilder.toString(); + } + + /** + * On where clause. + * + * @param metadata + * the metadata + * @param key + * the compound key object + * @param translator + * the translator + * @param queryBuilder + * the query builder + * @param compoundKey + * the compound key + */ + private void onWhereClause(EntityMetadata metadata, Object key, CQLTranslator translator, + StringBuilder queryBuilder, MetamodelImpl metaModel) + { + queryBuilder.append(CQLTranslator.ADD_WHERE_CLAUSE); + + if (metaModel.isEmbeddable(metadata.getIdAttribute().getBindableJavaType())) + { + Field[] fields = metadata.getIdAttribute().getBindableJavaType().getDeclaredFields(); + EmbeddableType compoundKey = metaModel.embeddable(metadata.getIdAttribute().getBindableJavaType()); + + for (Field field : fields) + { + if (field != null && !Modifier.isStatic(field.getModifiers()) + && !Modifier.isTransient(field.getModifiers()) && !field.isAnnotationPresent(Transient.class)) + { + Attribute attribute = compoundKey.getAttribute(field.getName()); + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + translator.buildWhereClause(queryBuilder, columnName, field, key); + } + } + } + else + { + Attribute attribute = metadata.getIdAttribute(); + translator.buildWhereClause(queryBuilder, + ((AbstractAttribute) metadata.getIdAttribute()).getBindableJavaType(), + CassandraUtilities.getIdColumnName(metadata, getExternalProperties()), key, translator.EQ_CLAUSE); + } + + // strip last "AND" clause. + queryBuilder.delete(queryBuilder.lastIndexOf(CQLTranslator.AND_CLAUSE), queryBuilder.length()); + } + + /** + * Find. + * + * @param entityClass + * the entity class + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param metadata + * the metadata + * @param rowIds + * the row ids + * @return the list + */ + public abstract List find(Class entityClass, List relationNames, boolean isWrapReq, + EntityMetadata metadata, Object... rowIds); + + /** + * Load super columns. + * + * @param keyspace + * the keyspace + * @param columnFamily + * the column family + * @param rowId + * the row id + * @param superColumnNames + * the super column names + * @return the list + */ + protected abstract List loadSuperColumns(String keyspace, String columnFamily, String rowId, + String... superColumnNames); + + /** + * Query related methods. + * + * @param cqlQuery + * the cql query + * @param clazz + * the clazz + * @param relationalField + * the relational field + * @return the list + */ + public abstract List executeQuery(String cqlQuery, Class clazz, List relationalField); + + /** + * Find. + * + * @param ixClause + * the ix clause + * @param m + * the m + * @param isRelation + * the is relation + * @param relations + * the relations + * @param maxResult + * the max result + * @param columns + * the columns + * @return the list + */ + public abstract List find(List ixClause, EntityMetadata m, boolean isRelation, List relations, + int maxResult, List columns); + + /** + * Find by range. + * + * @param muinVal + * the muin val + * @param maxVal + * the max val + * @param m + * the m + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param columns + * the columns + * @param conditions + * the conditions + * @return the list + * @throws Exception + * the exception + */ + public abstract List findByRange(byte[] muinVal, byte[] maxVal, EntityMetadata m, boolean isWrapReq, + List relations, List columns, List conditions, int maxResults) + throws Exception; + + /** + * Search in inverted index. + * + * @param columnFamilyName + * the column family name + * @param m + * the m + * @param indexClauseMap + * the index clause map + * @return the list + */ + public abstract List searchInInvertedIndex(String columnFamilyName, EntityMetadata m, + Map> indexClauseMap); + + /** + * Find. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param conditions + * the conditions + * @param maxResult + * the max result + * @param columns + * the columns + * @return the list + */ + public abstract List find(EntityMetadata m, List relationNames, + List conditions, int maxResult, List columns); + + /** + * Gets the data handler. + * + * @return the data handler + */ + protected abstract CassandraDataHandler getDataHandler(); + + /** + * Delete. + * + * @param entity + * the entity + * @param pKey + * the key + */ + protected abstract void delete(Object entity, Object pKey); + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.api.Batcher#addBatch(com.impetus.kundera + * .graph.Node) + */ + /** + * Adds the batch. + * + * @param node + * the node + */ + public void addBatch(Node node) + { + + if (node != null) + { + nodes.add(node); + } + + onBatchLimit(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#getBatchSize() + */ + /** + * Gets the batch size. + * + * @return the batch size + */ + public int getBatchSize() + { + return batchSize; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#clear() + */ + public void clear() + { + if (nodes != null) + { + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + } + + if (ttlPerSession) + { + ttlValues.clear(); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#executeBatch() + */ + /** + * Execute batch. + * + * @return the int + */ + public int executeBatch() + { + Cassandra.Client conn = null; + Object pooledConnection = null; + + /** + * Key -> Entity Class Value -> Map containing Row ID as Key and + * Mutation List as Value + */ + Map, Map>>> batchMutationMap = new HashMap, Map>>>(); + + int recordsExecuted = 0; + String batchQuery = CQLTranslator.BATCH_QUERY; + batchQuery = StringUtils.replace(batchQuery, CQLTranslator.STATEMENT, ""); + StringBuilder batchQueryBuilder = new StringBuilder(batchQuery); + try + { + boolean isCql3Enabled = false; + for (Node node : nodes) + { + if (node.isDirty()) + { + node.handlePreEvent(); + Object entity = node.getData(); + Object id = node.getEntityId(); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(node.getDataClass()); + persistenceUnit = metadata.getPersistenceUnit(); + isUpdate = node.isUpdate(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetamodel(metadata.getPersistenceUnit()); + + // delete can not be executed in batch + + if (isCql3Enabled(metadata)) + { + isCql3Enabled = true; + List relationHolders = getRelationHolders(node); + // onPersist(metadata, entity, id, relationHolders); + String query; + if (node.isInState(RemovedState.class)) + { + query = onDeleteQuery(metadata, metaModel, id); + } + else + { + query = createInsertQuery(metadata, entity, conn, relationHolders, + getTtlValues().get(metadata.getTableName())); + } + batchQueryBuilder.append(query); + } + else + { + if (node.isInState(RemovedState.class)) + { + delete(entity, id); + } + else + { + List relationHolders = getRelationHolders(node); + Map>> mutationMap = new HashMap>>(); + mutationMap = prepareMutation(metadata, entity, id, relationHolders, mutationMap); + + recordsExecuted += mutationMap.size(); + if (!batchMutationMap.containsKey(metadata.getEntityClazz())) + { + batchMutationMap.put(metadata.getEntityClazz(), mutationMap); + } + else + { + batchMutationMap.get(metadata.getEntityClazz()).putAll(mutationMap); + } + + indexNode(node, metadata); + } + } + node.handlePostEvent(); + } + } + + // Write Mutation map to database + + if (!batchMutationMap.isEmpty()) + { + pooledConnection = getConection(); + conn = getConnection(pooledConnection); + + for (Class entityClass : batchMutationMap.keySet()) + { + conn.batch_mutate(batchMutationMap.get(entityClass), consistencyLevel); + } + + } + + if (!nodes.isEmpty() && isCql3Enabled) + { + batchQueryBuilder.append(CQLTranslator.APPLY_BATCH); + executeCQLQuery(batchQueryBuilder.toString(), false); + } + } + catch (Exception e) + { + log.error("Error while persisting record. Caused by: .", e); + throw new KunderaException(e); + } + finally + { + clear(); + if (pooledConnection != null) + { + releaseConnection(pooledConnection); + } + } + + return recordsExecuted; + } + + /** + * Prepare mutation. + * + * @param entityMetadata + * the entity metadata + * @param entity + * the entity + * @param id + * the id + * @param relationHolders + * the relation holders + * @param mutationMap + * the mutation map + * @return the map + */ + protected Map>> prepareMutation(EntityMetadata entityMetadata, + Object entity, Object id, List relationHolders, + Map>> mutationMap) + { + + if (!isOpen()) + { + throw new PersistenceException("ThriftClient is closed."); + } + + // check for counter column + if (isUpdate && entityMetadata.isCounterColumnType()) + { + log.warn("Invalid operation! {} is not possible over counter column of entity {}.", "Merge", + entityMetadata.getEntityClazz()); + throw new UnsupportedOperationException("Invalid operation! Merge is not possible over counter column."); + } + + ThriftRow tf = null; + try + { + String columnFamily = entityMetadata.getTableName(); + tf = getDataHandler().toThriftRow(entity, id, entityMetadata, columnFamily, + getTtlValues().get(columnFamily)); + } + catch (Exception e) + { + log.error("Error during persisting record for entity {}, Caused by: .", entityMetadata.getEntityClazz(), + entityMetadata.getTableName(), e); + throw new KunderaException(e); + } + + addRelationsToThriftRow(entityMetadata, tf, relationHolders); + + String columnFamily = entityMetadata.getTableName(); + // Create Insertion List + List mutationList = new ArrayList(); + + /*********** Handling for counter column family ************/ + + if (entityMetadata.isCounterColumnType()) + { + List thriftCounterColumns = tf.getCounterColumns(); + List thriftCounterSuperColumns = tf.getCounterSuperColumns(); + + if (thriftCounterColumns != null && !thriftCounterColumns.isEmpty()) + { + for (CounterColumn column : thriftCounterColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setCounter_column(column)); + mutationList.add(mut); + } + } + + if (thriftCounterSuperColumns != null && !thriftCounterSuperColumns.isEmpty()) + { + for (CounterSuperColumn sc : thriftCounterSuperColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setCounter_super_column(sc)); + mutationList.add(mut); + } + } + } + else + /********* Handling for column family and super column family *********/ + { + List thriftColumns = tf.getColumns(); + List thriftSuperColumns = tf.getSuperColumns(); + + // Populate Insertion list for columns + if (thriftColumns != null && !thriftColumns.isEmpty()) + { + for (Column column : thriftColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setColumn(column)); + mutationList.add(mut); + } + } + + // Populate Insertion list for super columns + if (thriftSuperColumns != null && !thriftSuperColumns.isEmpty()) + { + for (SuperColumn superColumn : thriftSuperColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setSuper_column(superColumn)); + mutationList.add(mut); + } + } + } + + // Create Mutation Map + Map> columnFamilyValues = new HashMap>(); + columnFamilyValues.put(columnFamily, mutationList); + Bytes b = CassandraUtilities.toBytes(tf.getId(), entityMetadata.getIdAttribute().getBindableJavaType()); + mutationMap.put(b.getBytes(), columnFamilyValues); + + return mutationMap; + } + + /** + * Check on batch limit. + */ + private void onBatchLimit() + { + if (batchSize > 0 && batchSize == nodes.size()) + { + executeBatch(); + nodes.clear(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.client.ClientPropertiesSetter#populateClientProperties + * (com.impetus.kundera.client.Client, java.util.Map) + */ + @Override + public void populateClientProperties(Client client, Map properties) + { + new CassandraClientProperties().populateClientProperties(client, properties); + } + + /** + * Returns raw cassandra client from thrift connection pool. + * + * @param persistenceUnit + * persistence unit. + * @param schema + * schema or keyspace. + * @return raw cassandra client. + */ + protected Cassandra.Client getRawClient(final String persistenceUnit, final String schema) + { + Cassandra.Client client = null; + Object pooledConnection; + pooledConnection = getConection(); + client = getConnection(pooledConnection); + try + { + client.set_cql_version(getCqlVersion()); + } + catch (Exception e) + { + log.error("Error during borrowing a connection for persistence unit {}, Caused by: .", persistenceUnit, e); + throw new KunderaException(e); + } + finally + { + releaseConnection(pooledConnection); + } + return client; + + } + + /** + * Return the generated value of id. + * + * @param descriptor + * @param pu + * @return + */ + public Long getGeneratedValue(TableGeneratorDiscriptor descriptor, String pu) + { + Cassandra.Client conn = getRawClient(pu, descriptor.getSchema()); + try + { + conn.set_keyspace(descriptor.getSchema()); + ColumnPath columnPath = new ColumnPath(descriptor.getTable()); + columnPath.setColumn(descriptor.getValueColumnName().getBytes()); + long latestCount = 0l; + + try + { + latestCount = conn.get(ByteBuffer.wrap(descriptor.getPkColumnValue().getBytes()), columnPath, + getConsistencyLevel()).counter_column.value; + } + catch (NotFoundException e) + { + log.warn("Counter value not found for {}, resetting it to zero.", descriptor.getPkColumnName()); + latestCount = 0; + } + ColumnParent columnParent = new ColumnParent(descriptor.getTable()); + + CounterColumn counterColumn = new CounterColumn( + ByteBuffer.wrap(descriptor.getValueColumnName().getBytes()), 1); + + conn.add(ByteBuffer.wrap(descriptor.getPkColumnValue().getBytes()), columnParent, counterColumn, + getConsistencyLevel()); + + if (latestCount == 0) + { + return (long) descriptor.getInitialValue(); + } + else + { + return (latestCount + 1) * descriptor.getAllocationSize(); + } + } + catch (UnavailableException e) + { + log.error("Error while reading counter value from table{}, Caused by: .", descriptor.getTable(), e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while reading counter value from table{}, Caused by: .", descriptor.getTable(), e); + throw new KunderaException(e); + } + catch (Exception e) + { + log.error("Error while using keyspace. Caused by: .", e); + throw new KunderaException(e); + } + } + + /** + * Executes query string using cql3. + * + * @param cqlQuery + * @return + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + * @throws TException + */ + protected CqlResult executeCQLQuery(String cqlQuery, boolean isCql3Enabled) throws InvalidRequestException, + UnavailableException, TimedOutException, SchemaDisagreementException, TException + { + Cassandra.Client conn = null; + Object pooledConnection = null; + pooledConnection = getConection(); + conn = getConnection(pooledConnection); + try + { + if (isCql3Enabled || isCql3Enabled()) + { + return conn.execute_cql3_query(ByteBufferUtil.bytes(cqlQuery), + org.apache.cassandra.thrift.Compression.NONE, consistencyLevel); + } + + if (log.isInfoEnabled()) + { + log.info("Executing cql query {}.", cqlQuery); + } + return conn.execute_cql_query(ByteBufferUtil.bytes(cqlQuery), org.apache.cassandra.thrift.Compression.NONE); + } + finally + { + releaseConnection(pooledConnection); + } + } + + /** + * Find List of objects based on value {@columnValue} of column + * {@columnName} + * + * @param m + * @param columnName + * @param columnValue + * @param clazz + * @param dataHandler + * @return + */ + protected List findByRelationQuery(EntityMetadata m, String columnName, Object columnValue, Class clazz, + CassandraDataHandler dataHandler) + { + return cqlClient.findByRelationQuery(m, columnName, columnValue, clazz, dataHandler); + } + + /** + * @param persistenceUnit + * @param puProperties + */ + private void setBatchSize(String persistenceUnit, Map puProperties) + { + String batch_Size = null; + if (puProperties != null) + { + batch_Size = puProperties != null ? (String) puProperties.get(PersistenceProperties.KUNDERA_BATCH_SIZE) + : null; + if (batch_Size != null) + { + batchSize = Integer.valueOf(batch_Size); + if (batchSize == 0) + { + throw new IllegalArgumentException("kundera.batch.size property must be numeric and > 0."); + } + } + } + else if (batch_Size == null) + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + batchSize = puMetadata != null ? puMetadata.getBatchSize() : 0; + } + } + + private void populateCqlVersion(Map externalProperties) + { + String cqlVersion = externalProperties != null ? (String) externalProperties + .get(CassandraConstants.CQL_VERSION) : null; + if (cqlVersion == null + || !(cqlVersion != null && (cqlVersion.equals(CassandraConstants.CQL_VERSION_2_0) || cqlVersion + .equals(CassandraConstants.CQL_VERSION_3_0)))) + { + cqlVersion = (CassandraPropertyReader.csmd != null ? CassandraPropertyReader.csmd.getCqlVersion() + : CassandraConstants.CQL_VERSION_2_0); + } + + if (cqlVersion.equals(CassandraConstants.CQL_VERSION_3_0)) + { + setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + } + else + { + setCqlVersion(CassandraConstants.CQL_VERSION_2_0); + } + } + + /** + * Return cassandra client instance. + * + * @param connection + * @return + */ + private Cassandra.Client getConnection(Object connection) + { + if (connection != null) + { + if (connection.getClass().isAssignableFrom(Connection.class)) + { + return ((Connection) connection).getClient(); + } + else + { + return ((IPooledConnection) connection).getAPI(); + } + } + + throw new KunderaException("Invalid configuration!, no available pooled connection found for:" + + this.getClass().getSimpleName()); + } + + protected abstract Object getConection(); + + protected abstract void releaseConnection(Object conn); + + /** + * Use CqlClient class for crud when cql enable. + * + * + * @author Kuldeep Mishra + * + */ + protected class CQLClient + { + public void persist(EntityMetadata entityMetadata, Object entity, + org.apache.cassandra.thrift.Cassandra.Client conn, List rlHolders, Object ttlColumns) + throws UnsupportedEncodingException, InvalidRequestException, TException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + String query; + if (entityMetadata.isCounterColumnType()) + { + query = createUpdateQueryForCounter(entityMetadata, entity, conn, rlHolders); + } + else + { + query = createInsertQuery(entityMetadata, entity, conn, rlHolders, ttlColumns); + } + // conn.set_cql_version(getCqlVersion()); + conn.execute_cql3_query(ByteBuffer.wrap(query.getBytes(Constants.CHARSET_UTF8)), Compression.NONE, + consistencyLevel); + } + + /** + * Execute query and Return list of Objects. + * + * @param cqlQuery + * @param clazz + * @param relationalField + * @param dataHandler + * @return + */ + public List executeQuery(String cqlQuery, Class clazz, List relationalField, + CassandraDataHandler dataHandler, boolean isCql3Enabled) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(clazz); + CqlResult result = null; + List returnedEntities = new ArrayList(); + try + { + if (log.isInfoEnabled()) + { + log.info("Executing query {}.", cqlQuery); + } + result = executeCQLQuery(cqlQuery, isCql3Enabled); + if (result != null && (result.getRows() != null || result.getRowsSize() > 0)) + { + returnedEntities = new ArrayList(result.getRowsSize()); + Iterator iter = result.getRowsIterator(); + while (iter.hasNext()) + { + CqlRow row = iter.next(); + Object rowKey = null; + + ThriftRow thriftRow = null; + thriftRow = new ThriftRow(rowKey, entityMetadata.getTableName(), row.getColumns(), + new ArrayList(0), new ArrayList(0), + new ArrayList(0)); + + Object entity = dataHandler.populateEntity(thriftRow, entityMetadata, relationalField, + relationalField != null && !relationalField.isEmpty()); + + if (entity != null) + { + returnedEntities.add(entity); + } + else + { + returnedEntities.add(row.getColumns().get(0)); + } + } + } + } + catch (Exception e) + { + log.error("Error while executing native CQL query Caused by: .", e); + throw new PersistenceException(e); + } + + return returnedEntities; + } + + /** + * Finds entity on the basis of rowid and return list of objects. + * + * @param metaModel + * @param metadata + * @param rowId + * @param relationNames + * @return + */ + public List find(MetamodelImpl metaModel, EntityMetadata metadata, Object rowId, + List relationNames) + { + CQLTranslator translator = new CQLTranslator(); + String select_Query = translator.SELECTALL_QUERY; + select_Query = StringUtils.replace(select_Query, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), metadata.getTableName()).toString()); + StringBuilder builder = new StringBuilder(select_Query); + onWhereClause(metadata, rowId, translator, builder, metaModel); + return CassandraClientBase.this.executeQuery(builder.toString(), metadata.getEntityClazz(), relationNames); + } + + /** + * Find List of objects based on value {@columnValue} of column + * {@columnName} + * + * @param m + * @param columnName + * @param columnValue + * @param clazz + * @param dataHandler + * @return + */ + protected List findByRelationQuery(EntityMetadata m, String columnName, Object columnValue, + Class clazz, CassandraDataHandler dataHandler) + { + CQLTranslator translator = new CQLTranslator(); + String selectQuery = translator.SELECTALL_QUERY; + selectQuery = StringUtils.replace(selectQuery, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), m.getTableName()).toString()); + + StringBuilder selectQueryBuilder = new StringBuilder(selectQuery); + selectQueryBuilder.append(CQLTranslator.ADD_WHERE_CLAUSE); + + translator.buildWhereClause(selectQueryBuilder, columnValue.getClass(), columnName, columnValue, "="); + selectQueryBuilder.delete(selectQueryBuilder.lastIndexOf(CQLTranslator.AND_CLAUSE), + selectQueryBuilder.length()); + return executeQuery(selectQueryBuilder.toString(), clazz, m.getRelationNames(), dataHandler, true); + } + } + + /** + * @return the ttlPerRequest + */ + public boolean isTtlPerRequest() + { + return ttlPerRequest; + } + + /** + * @param ttlPerRequest + * the ttlPerRequest to set + */ + public void setTtlPerRequest(boolean ttlPerRequest) + { + this.ttlPerRequest = ttlPerRequest; + } + + /** + * @return the ttlPerSession + */ + public boolean isTtlPerSession() + { + return ttlPerSession; + } + + /** + * @param ttlPerSession + * the ttlPerSession to set + */ + public void setTtlPerSession(boolean ttlPerSession) + { + this.ttlPerSession = ttlPerSession; + } + + /** + * @return the ttlValues + */ + public Map getTtlValues() + { + return ttlValues; + } + + /** + * @param ttlValues + * the ttlValues to set + */ + public void setTtlValues(Map ttlValues) + { + this.ttlValues = ttlValues; + } + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientProperties.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientProperties.java new file mode 100644 index 000000000..07e6f1288 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/CassandraClientProperties.java @@ -0,0 +1,86 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra; + +import java.util.Map; + +import org.apache.cassandra.thrift.ConsistencyLevel; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientPropertiesSetter; + +/** + * Cassandra implementation of {@link ClientPropertiesSetter} + * + * @author amresh.singh + */ +class CassandraClientProperties +{ + private static final String TTL_VALUES = "ttl.values"; + + private static final String TTL_PER_REQUEST = "ttl.per.request"; + + private static final String TTL_PER_SESSION = "ttl.per.session"; + + private static final String CONSISTENCY_LEVEL = "consistency.level"; + + private static final String CQL_VERSION = CassandraConstants.CQL_VERSION; + + public void populateClientProperties(Client client, Map properties) + { + CassandraClientBase cassandraClientBase = (CassandraClientBase) client; + + if (properties != null) + { + for (String key : properties.keySet()) + { + Object value = properties.get(key); + if (key.equals(CONSISTENCY_LEVEL) && value instanceof ConsistencyLevel) + { + cassandraClientBase.setConsistencyLevel((ConsistencyLevel) value); + } + else if (key.equals(CQL_VERSION) && value instanceof String) + { + cassandraClientBase.setCqlVersion((String) value); + } + else if (key.equals(TTL_PER_SESSION) && value instanceof Boolean) + { + if(((Boolean) value).booleanValue()) + { + cassandraClientBase.setTtlPerRequest(false); + } + cassandraClientBase.setTtlPerSession((Boolean) value); + + } + else if (key.equals(TTL_PER_REQUEST) && value instanceof Boolean) + { + if(((Boolean) value).booleanValue()) + { + cassandraClientBase.setTtlPerSession(false); + } + cassandraClientBase.setTtlPerRequest((Boolean) value); + } + else if (key.equals(TTL_VALUES) && value instanceof Map) + { + cassandraClientBase.setTtlValues((Map) value); + } + + // Add more properties as needed + } + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraConstants.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraConstants.java new file mode 100644 index 000000000..477b8c865 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraConstants.java @@ -0,0 +1,95 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.common; + +/** + * Holds constants for kundera-cassandra module + * + * @author amresh.singh + */ +public interface CassandraConstants +{ + public static final String CQL_VERSION_2_0 = "2.0.0"; + + public static final String CQL_VERSION_3_0 = "3.0.0"; + + // properties to set during creation of keyspace. + public static final String PLACEMENT_STRATEGY = "strategy.class"; + + public static final String REPLICATION_FACTOR = "replication.factor"; + + public static final String CF_DEFS = "cf.defs"; + + public static final String DATA_CENTERS = "datacenters"; + + public static final String INVERTED_INDEXING_ENABLED = "inverted.indexing.enabled"; + + /** + * + */ + public static final String DEFAULT_REPLICATION_FACTOR = "1"; + + public static final String DURABLE_WRITES = "durable.writes"; + + // properties to set during creation of column family. + + public static final String DEFAULT_VALIDATION_CLASS = "default.validation.class"; + + public static final String KEY_VALIDATION_CLASS = "key.validation.class"; + + public static final String COMPARATOR_TYPE = "comparator.type"; + + public static final String SUBCOMPARATOR_TYPE = "subcomparator.type"; + + public static final String REPLICATE_ON_WRITE = "replicate.on.write"; + + public static final String COMPACTION_STRATEGY = "compaction.strategy"; + + public static final String MAX_COMPACTION_THRESHOLD = "max.compaction.threshold"; + + public static final String MIN_COMPACTION_THRESHOLD = "min.compaction.threshold"; + + public static final String COMMENT = "comment"; + + public static final String ID = "id"; + + public static final String CACHING = "caching"; + + public static final String BLOOM_FILTER_FP_CHANCE = "bloom.filter.fp.chance"; + + public static final String GC_GRACE_SECONDS = "gc.grace.seconds"; + + public static final String READ_REPAIR_CHANCE = "read.repair.chance"; + + public static final String DCLOCAL_READ_REPAIR_CHANCE = "dclocal.read.repair.chance"; + + public static final String CQL_VERSION = "cql.version"; + + /** Name of Row key column when stored using CQL insert statement */ + public static final String CQL_KEY = "key"; + + public static final String TEST_ON_BORROW = "testonborrow"; + + public static final String TEST_ON_CONNECT = "testonconnect"; + + public static final String TEST_WHILE_IDLE = "testwhileidle"; + + public static final String TEST_ON_RETURN = "testonretrun"; + + public static final String SOCKET_TIMEOUT = "socket.timeout"; + + public static final String MAX_WAIT = "max.wait"; +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraUtilities.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraUtilities.java new file mode 100644 index 000000000..6e39eb894 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/common/CassandraUtilities.java @@ -0,0 +1,202 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.common; + +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.lang.StringUtils; +import org.scale7.cassandra.pelops.Bytes; + +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.accessor.DateAccessor; + +/** + * Provides utilities methods + * + * @author amresh.singh + */ +public class CassandraUtilities +{ + + public static String toUTF8(byte[] value) + { + return value == null ? null : new String(value, Charset.forName(Constants.CHARSET_UTF8)); + } + + public static String getKeyspace(String persistenceUnit) + { + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit); + Properties props = persistenceUnitMetadata.getProperties(); + String keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + return keyspace; + } + + public static Bytes toBytes(Object value, Field f) + { + return toBytes(value, f.getType()); + + } + + + public static byte[] toBytes(final Object value) + { + if(value != null) + { + return toBytes(value,value.getClass()).toByteArray(); + } + + return null; + } + /** + * @param value + * @param f + * @return + */ + public static Bytes toBytes(Object value, Class clazz) + { + if (clazz.isAssignableFrom(String.class)) + { + return Bytes.fromByteArray(((String) value).getBytes()); + } + else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) + { + return Bytes.fromInt(Integer.parseInt(value.toString())); + } + else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) + { + return Bytes.fromLong(Long.parseLong(value.toString())); + } + else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) + { + return Bytes.fromBoolean(Boolean.valueOf(value.toString())); + } + else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) + { + return Bytes.fromDouble(Double.valueOf(value.toString())); + } + else if (clazz.isAssignableFrom(java.util.UUID.class)) + { + return Bytes.fromUuid(UUID.fromString(value.toString())); + } + else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) + { + return Bytes.fromFloat(Float.valueOf(value.toString())); + } + else if (clazz.isAssignableFrom(Date.class)) + { + DateAccessor dateAccessor = new DateAccessor(); + return Bytes.fromByteArray(dateAccessor.toBytes(value)); + } + else + { + if (value.getClass().isAssignableFrom(String.class)) + { + value = PropertyAccessorFactory.getPropertyAccessor(clazz).fromString(clazz, value.toString()); + } + return Bytes.fromByteArray(PropertyAccessorFactory.getPropertyAccessor(clazz).toBytes(value)); + } + } + + /** + * Append columns. + * + * @param builder + * the builder + * @param columns + * the columns + * @param selectQuery + * the select query + * @param translator + * the translator + */ + public static StringBuilder appendColumns(StringBuilder builder, List columns, String selectQuery, + CQLTranslator translator) + { + if (columns != null) + { + for (String column : columns) + { + translator.appendColumnName(builder, column); + builder.append(","); + } + } + if (builder.lastIndexOf(",") != -1) + { + builder.deleteCharAt(builder.length() - 1); + // selectQuery = StringUtils.replace(selectQuery, + // CQLTranslator.COLUMN_FAMILY, builder.toString()); + selectQuery = StringUtils.replace(selectQuery, CQLTranslator.COLUMNS, builder.toString()); + } + + builder = new StringBuilder(selectQuery); + return builder; + } + + /** + * Return name if Idcolumn for cql, returns {@CassandraConstants.CQL_KEY + * + * + * + * + * } if user opted for + * {@PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE + * + * + * + * + * } otherwise returns + * JPAColumnName of id attribute. + * + * @param m + * @param externalProperties + * @return + */ + public static String getIdColumnName(final EntityMetadata m, final Map externalProperties) + { + // key for auto schema generation. + String persistenceUnit = m.getPersistenceUnit(); + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit); + String autoDdlOption = externalProperties != null ? (String) externalProperties + .get(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) : null; + if (autoDdlOption == null) + { + autoDdlOption = persistenceUnitMetadata != null ? persistenceUnitMetadata + .getProperty(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) : null; + } + + // check if id attribute is embeddable + boolean containsBasicCollectionField = MetadataUtils.containsBasicElementCollectionField(m); + return autoDdlOption == null || containsBasicCollectionField ? ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName() + : CassandraConstants.CQL_KEY; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/config/CassandraPropertyReader.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/config/CassandraPropertyReader.java new file mode 100644 index 000000000..802285a9f --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/config/CassandraPropertyReader.java @@ -0,0 +1,290 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.locator.SimpleStrategy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.kundera.configure.AbstractPropertyReader; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection.Server; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema.Table; +import com.impetus.kundera.configure.PropertyReader; + +/** + * Cassandra Property Reader reads cassandra properties from property file + * {kundera-cassandra.properties} and put it into cassandra schema metadata. + * + * @author kuldeep.mishra + * + */ +public class CassandraPropertyReader extends AbstractPropertyReader implements PropertyReader +{ + /** The log instance. */ + private Logger logger = LoggerFactory.getLogger(CassandraPropertyReader.class); + + /** csmd instance of CassandraSchemaMetadata */ + + public static CassandraSchemaMetadata csmd; + + public CassandraPropertyReader(Map externalProperties) + { + super(externalProperties); + csmd = new CassandraSchemaMetadata(); + } + + public void onXml(ClientProperties cp) + { + if (cp != null) + { + csmd.setClientProperties(cp); + } + } + + /** + * Cassandra schema metadata holds metadata information. + * + * @author kuldeep.mishra + * + */ + public class CassandraSchemaMetadata + { + + private ClientProperties clientProperties; + + /** + * @param parseXML + */ + private void setClientProperties(ClientProperties clientProperties) + { + this.clientProperties = clientProperties; + } + + /** + * @return the clientProperties + */ + public ClientProperties getClientProperties() + { + return clientProperties; + } + + /** + * @return the replication_factor + */ + public String getReplication_factor(String schemaName) + { + Schema schema = getSchema(schemaName); + String replication = "1"; + if (schema != null && schema.getSchemaProperties() != null && !schema.getSchemaProperties().isEmpty()) + { + replication = schema.getSchemaProperties().getProperty(CassandraConstants.REPLICATION_FACTOR); + } + + if (logger.isInfoEnabled()) + { + logger.info("Returning replication factor value {}", replication); + } + return replication; + } + + /** + * @return the placement_strategy + */ + public String getPlacement_strategy(String schemaName) + { + Schema schema = getSchema(schemaName); + String placementStrategy = SimpleStrategy.class.getName(); + if (schema != null && schema.getSchemaProperties() != null && !schema.getSchemaProperties().isEmpty()) + { + placementStrategy = schema.getSchemaProperties().getProperty(CassandraConstants.PLACEMENT_STRATEGY); + } + + if (logger.isInfoEnabled()) + { + logger.info("Returning placement strategy value {}", placementStrategy); + } + return placementStrategy; + } + + public boolean isCounterColumn(String schemaName, String cfName) + { + Table table = getColumnFamily(schemaName, cfName); + if (table != null) + { + return table.getProperties().getProperty(CassandraConstants.DEFAULT_VALIDATION_CLASS) + .equalsIgnoreCase(CounterColumnType.class.getSimpleName()) ? true : false; + } + return false; + } + + public DataStore getDataStore() + { + if (getClientProperties() != null) + { + if (getClientProperties().getDatastores() != null) + { + for (DataStore dataStore : getClientProperties().getDatastores()) + { + if (dataStore.getName() != null && dataStore.getName().equalsIgnoreCase("cassandra")) + { + return dataStore; + } + } + } + + if (logger.isWarnEnabled()) + { + logger.warn("No data store configuration found, returning null."); + } + } + return null; + } + + public boolean isInvertedIndexingEnabled(String schemaName) + { + boolean result = false; + if (schemaName != null && getDataStore() != null && getDataStore().getSchemas() != null) + { + for (Schema schema : getDataStore().getSchemas()) + { + if (schema != null && schemaName.equals(schema.getName()) && schema.getSchemaProperties() != null + && schema.getSchemaProperties() != null) + { + result = Boolean.parseBoolean((String) schema.getSchemaProperties().get( + CassandraConstants.INVERTED_INDEXING_ENABLED)); + break; + } + } + if (logger.isWarnEnabled()) + { + logger.warn("Returning inverted indexing enabled value {}.", result); + } + } + return result; + } + + public String getCqlVersion() + { + if (getDataStore() != null) + { + Properties properties = getDataStore().getConnection() != null ? getDataStore().getConnection() + .getProperties() : null; + + if (properties != null) + { + String cqlVersion = properties.getProperty(CassandraConstants.CQL_VERSION); + if (cqlVersion != null) + { + if (cqlVersion.equalsIgnoreCase(CassandraConstants.CQL_VERSION_3_0) + || cqlVersion.equalsIgnoreCase(CassandraConstants.CQL_VERSION_2_0)) + { + return cqlVersion; + } + else + { + logger.warn("Invalid {} cql version provided, valid are {},{}.", cqlVersion, + CassandraConstants.CQL_VERSION_2_0, CassandraConstants.CQL_VERSION_3_0); + } + } + } + } + return CassandraConstants.CQL_VERSION_2_0; + } + + public Schema getSchema(String schemaName) + { + if (getDataStore() != null) + { + List schemas = getDataStore().getSchemas(); + if (schemas != null && !schemas.isEmpty()) + { + for (Schema s : schemas) + { + if (s != null && s.getName() != null && s.getName().equalsIgnoreCase(schemaName)) + { + return s; + } + } + } + } + return null; + } + + public Table getColumnFamily(String schemaName, String cfName) + { + Schema schema = getSchema(schemaName); + if (schema != null) + { + if (schema.getTables() != null) + { + for (Table table : schema.getTables()) + { + if (table != null && table.getName() != null && table.getName().equalsIgnoreCase(cfName)) + { + return table; + } + } + if (logger.isWarnEnabled()) + { + logger.warn("No column family schema found, returning null."); + } + } + } + return null; + } + + public Properties getConnectionProperties() + { + DataStore ds = getDataStore(); + Properties properties = new Properties(); + if (ds != null) + { + if (ds.getConnection() != null) + { + properties = ds.getConnection().getProperties(); + return properties != null ? properties : new Properties(); + } + if (logger.isWarnEnabled()) + { + logger.warn("No connection properties found, returning none."); + } + } + return properties; + } + + public List getConnectionServers() + { + DataStore ds = getDataStore(); + List servers = new ArrayList(); + if (ds != null && ds.getConnection() != null) + { + servers = ds.getConnection().getServers(); + return servers; + } + return servers; + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandler.java new file mode 100644 index 000000000..680354b71 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandler.java @@ -0,0 +1,121 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.datahandler; + +import java.util.List; + +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.SuperColumn; + +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.db.DataRow; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Defines low level translation methods for Cassandra. + * + * @author amresh.singh + */ +public interface CassandraDataHandler +{ + + /** + * From thrift row. + * + * @param + * the element type + * @param clazz + * the clazz + * @param m + * the m + * @param tr + * the tr + * @return the e + * @throws Exception + * the exception + */ + E fromThriftRow(Class clazz, EntityMetadata m, DataRow tr) throws Exception; + + /** + * From thrift row. + * + * @param clazz + * the clazz + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param consistencyLevel + * the consistency level + * @param rowIds + * the row ids + * @return the list + * @throws Exception + * the exception + */ + List fromThriftRow(Class clazz, EntityMetadata m, List relationNames, boolean isWrapReq, + ConsistencyLevel consistencyLevel, Object... rowIds) throws Exception; + + /** + * From thrift row. + * + * @param clazz + * the clazz + * @param m + * the m + * @param rowKey + * the row key + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param consistencyLevel + * the consistency level + * @return the object + * @throws Exception + * the exception + */ + Object fromThriftRow(Class clazz, EntityMetadata m, Object rowKey, List relationNames, + boolean isWrapReq, ConsistencyLevel consistencyLevel) throws Exception; + + /** + * Populate entity. + * + * @param tr + * the tr + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @return the object + */ + Object populateEntity(ThriftRow tr, EntityMetadata m, List relationNames, boolean isWrapReq); + + /** + * @param e + * @param id + * @param m + * @param columnFamily + * @param columnTTLs TODO + * @return + * @throws Exception + */ + ThriftRow toThriftRow(Object e, Object id, EntityMetadata m, String columnFamily, Object columnTTLs) throws Exception; +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandlerBase.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandlerBase.java new file mode 100644 index 000000000..bc5ff2a9e --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/CassandraDataHandlerBase.java @@ -0,0 +1,1859 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.datahandler; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.PluralAttribute; + +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.ListType; +import org.apache.cassandra.db.marshal.MapType; +import org.apache.cassandra.db.marshal.SetType; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.CounterColumn; +import org.apache.cassandra.thrift.CounterSuperColumn; +import org.apache.cassandra.thrift.SuperColumn; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.schemamanager.CassandraValidationClassMapper; +import com.impetus.client.cassandra.thrift.ThriftDataResultHelper; +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.cache.ElementCollectionCacheManager; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.DataRow; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.property.accessor.DoubleAccessor; +import com.impetus.kundera.property.accessor.IntegerAccessor; +import com.impetus.kundera.property.accessor.LongAccessor; + +/** + * Base class for all Cassandra Data Handlers. + * + * @author amresh.singh + */ +public abstract class CassandraDataHandlerBase +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(CassandraDataHandlerBase.class); + + /** The thrift translator. */ + protected ThriftDataResultHelper thriftTranslator = new ThriftDataResultHelper(); + + private CassandraClientBase clientBase; + + public CassandraDataHandlerBase(CassandraClientBase clientBase) + { + this.clientBase = clientBase; + } + + /** + * From thrift row. + * + * @param + * the element type + * @param clazz + * the clazz + * @param m + * the m + * @param tr + * the cr + * @return the e + * @throws Exception + * the exception + */ + + public E fromThriftRow(Class clazz, EntityMetadata m, DataRow tr) throws Exception + { + + // Instantiate a new instance + E e = null; + + // Set row-key. Note: + // PropertyAccessorHelper.setId(e, m, tr.getId()); + + // Get a name->field map for super-columns + Map columnNameToFieldMap = new HashMap(); + Map superColumnNameToFieldMap = new HashMap(); + MetadataUtils.populateColumnAndSuperColumnMaps(m, columnNameToFieldMap, superColumnNameToFieldMap); + + Collection embeddedCollection = null; + Field embeddedCollectionField = null; + for (SuperColumn sc : tr.getColumns()) + { + if (e == null) + { + // Instantiate a new instance + e = clazz.newInstance(); + + // Set row-key. Note: + PropertyAccessorHelper.setId(e, m, tr.getId()); + } + + String scName = PropertyAccessorFactory.STRING.fromBytes(String.class, sc.getName()); + String scNamePrefix = null; + + if (scName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) != -1) + { + scNamePrefix = MetadataUtils.getEmbeddedCollectionPrefix(scName); + embeddedCollectionField = superColumnNameToFieldMap.get(scNamePrefix); + embeddedCollection = MetadataUtils.getEmbeddedCollectionInstance(embeddedCollectionField); + + Object embeddedObject = populateEmbeddedObject(sc, m); + embeddedCollection.add(embeddedObject); + PropertyAccessorHelper.set(e, embeddedCollectionField, embeddedCollection); + } + else + { + boolean intoRelations = false; + if (scName.equals(Constants.FOREIGN_KEY_EMBEDDED_COLUMN_NAME)) + { + intoRelations = true; + } + + for (Column column : sc.getColumns()) + { + if (column != null) + { + String name = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + byte[] value = column.getValue(); + + if (value == null) + { + continue; + } + + if (intoRelations) + { + Relation relation = m.getRelation(name); + + String foreignKeys = PropertyAccessorFactory.STRING.fromBytes(String.class, value); + Set keys = MetadataUtils.deserializeKeys(foreignKeys); + } + else + { + // set value of the field in the bean + Field field = columnNameToFieldMap.get(name); + Object embeddedObject = PropertyAccessorHelper.getObject(e, scName); + PropertyAccessorHelper.set(embeddedObject, field, value); + } + + } + + } + } + } + + if(log.isInfoEnabled()) + { + log.info("Returning entity {} for class {}", e,clazz); + } + return e; + } + + /** + * From thrift row. + * + * @param clazz + * the clazz + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param consistencyLevel + * the consistency level + * @param rowIds + * the row ids + * @return the list + * @throws Exception + * the exception + */ + public List fromThriftRow(Class clazz, EntityMetadata m, List relationNames, boolean isWrapReq, + ConsistencyLevel consistencyLevel, Object... rowIds) throws Exception + { + List entities = new ArrayList(); + if (rowIds != null) + { + for (Object rowKey : rowIds) + { + Object e = fromThriftRow(clazz, m, rowKey, relationNames, isWrapReq, consistencyLevel); + if (e != null) + { + entities.add(e); + } + } + } + return entities; + } + + /** + * From thrift row. + * + * @param clazz + * the clazz + * @param m + * the m + * @param rowKey + * the row key + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param consistencyLevel + * the consistency level + * @return the object + * @throws Exception + * the exception + */ + public abstract Object fromThriftRow(Class clazz, EntityMetadata m, Object rowKey, List relationNames, + boolean isWrapReq, ConsistencyLevel consistencyLevel) throws Exception; + + /** + * Populate embedded object. + * + * @param sc + * the sc + * @param m + * the m + * @return the object + * @throws Exception + * the exception + */ + private Object populateEmbeddedObject(SuperColumn sc, EntityMetadata m) throws Exception + { + Field embeddedCollectionField = null; + Object embeddedObject = null; + String scName = PropertyAccessorFactory.STRING.fromBytes(String.class, sc.getName()); + String scNamePrefix = null; + + // Get a name->field map for super-columns + Map columnNameToFieldMap = new HashMap(); + Map superColumnNameToFieldMap = new HashMap(); + MetadataUtils.populateColumnAndSuperColumnMaps(m, columnNameToFieldMap, superColumnNameToFieldMap); + + // If this super column is variable in number (name#sequence format) + if (scName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) != -1) + { + StringTokenizer st = new StringTokenizer(scName, Constants.EMBEDDED_COLUMN_NAME_DELIMITER); + if (st.hasMoreTokens()) + { + scNamePrefix = st.nextToken(); + } + + embeddedCollectionField = superColumnNameToFieldMap.get(scNamePrefix); + Class embeddedClass = PropertyAccessorHelper.getGenericClass(embeddedCollectionField); + + // must have a default no-argument constructor + try + { + embeddedClass.getConstructor(); + } + catch (NoSuchMethodException nsme) + { + throw new PersistenceException(embeddedClass.getName() + + " is @Embeddable and must have a default no-argument constructor."); + } + embeddedObject = embeddedClass.newInstance(); + + for (Column column : sc.getColumns()) + { + String name = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + byte[] value = column.getValue(); + if (value == null) + { + continue; + } + Field columnField = columnNameToFieldMap.get(name); + PropertyAccessorHelper.set(embeddedObject, columnField, value); + } + + } + else + { + Field superColumnField = superColumnNameToFieldMap.get(scName); + Class superColumnClass = superColumnField.getType(); + embeddedObject = superColumnClass.newInstance(); + + for (Column column : sc.getColumns()) + { + String name = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + byte[] value = column.getValue(); + + if (value == null) + { + continue; + } + // set value of the field in the bean + Field columnField = columnNameToFieldMap.get(name); + PropertyAccessorHelper.set(embeddedObject, columnField, value); + + } + } + return embeddedObject; + } + + /** + * Helper method to convert @Entity to ThriftRow. + * + * @param e + * the e + * @param id + * the id + * @param m + * the m + * @param columnFamily + * the colmun family + * @param columnTTLs TODO + * @return the base data accessor. thrift row + * @throws Exception + * the exception + */ + public ThriftRow toThriftRow(Object e, Object id, EntityMetadata m, String columnFamily, Object columnTTLs) throws Exception + { + // timestamp to use in thrift column objects + // long timestamp = System.currentTimeMillis(); + + ThriftRow tr = new ThriftRow(); + + tr.setColumnFamilyName(columnFamily); // column-family name + tr.setId(id); // Id + + long timestamp = System.currentTimeMillis(); + // Add super columns to thrift row + onColumnOrSuperColumnThriftRow(tr, m, e, id, timestamp, columnTTLs); + return tr; + } + + /** + * To index thrift row. + * + * @param e + * the e + * @param m + * the m + * @param columnFamily + * the column family + * @return the list + */ + public List toIndexThriftRow(Object e, EntityMetadata m, String columnFamily) + { + List indexThriftRows = new ArrayList(); + + byte[] rowKey = PropertyAccessorHelper.get(e, (Field) m.getIdAttribute().getJavaMember()); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + // Add thrift rows for embeddables + Map embeddables = metaModel.getEmbeddables(m.getEntityClazz()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + for (String embeddedFieldName : embeddables.keySet()) + { + EmbeddableType embeddedColumn = embeddables.get(embeddedFieldName); + + // Index embeddable only when specified by user + Field embeddedField = (Field) entityType.getAttribute(embeddedFieldName).getJavaMember(); + if (!MetadataUtils.isEmbeddedAtributeIndexable(embeddedField)) + { + continue; + } + + Object embeddedObject = PropertyAccessorHelper.getObject(e, + (Field) entityType.getAttribute(embeddedFieldName).getJavaMember()); + if (embeddedObject == null) + { + continue; + } + if (embeddedObject instanceof Collection) + { + ElementCollectionCacheManager ecCacheHandler = ElementCollectionCacheManager.getInstance(); + + for (Object obj : (Collection) embeddedObject) + { + // for (com.impetus.kundera.metadata.model.Column column : + // embeddedColumn.getColumns()) + for (Object column : embeddedColumn.getAttributes()) + { + + Attribute columnAttribute = (Attribute) column; + String columnName = columnAttribute.getName(); + if (!MetadataUtils.isColumnInEmbeddableIndexable(embeddedField, columnName)) + { + continue; + } + + // Column Value + String id = CassandraUtilities.toUTF8(rowKey); + String superColumnName = ecCacheHandler.getElementCollectionObjectName(id, obj); + + ThriftRow tr = constructIndexTableThriftRow(columnFamily, embeddedFieldName, obj, + columnAttribute, rowKey, superColumnName); + if (tr != null) + { + indexThriftRows.add(tr); + } + } + } + } + else + { + // for (com.impetus.kundera.metadata.model.Column column : + // embeddedColumn.getColumns()) + // { + for (Object column : embeddedColumn.getAttributes()) + { + + Attribute columnAttribute = (Attribute) column; + String columnName = columnAttribute.getName(); + Class columnClass = ((AbstractAttribute) columnAttribute).getBindableJavaType(); + if (!MetadataUtils.isColumnInEmbeddableIndexable(embeddedField, columnName) + || columnClass.equals(byte[].class)) + { + continue; + } + + // No EC Name + ThriftRow tr = constructIndexTableThriftRow(columnFamily, embeddedFieldName, embeddedObject, + (Attribute) column, rowKey, ""); + if (tr != null) + { + indexThriftRows.add(tr); + } + } + } + } + return indexThriftRows; + } + + /** + * Constructs Thrift Tow (each record) for Index Table. + * + * @param columnFamily + * Column family Name for Index Table + * @param embeddedFieldName + * the embedded field name + * @param obj + * Embedded Object instance + * @param column + * Instance of {@link Column} + * @param rowKey + * Name of Index Column + * @param ecValue + * Name of embeddable object in Element Collection cache (usually + * in the form of # + * @return Instance of {@link ThriftRow} + */ + private ThriftRow constructIndexTableThriftRow(String columnFamily, String embeddedFieldName, Object obj, + Attribute column, byte[] rowKey, String ecValue) + { + // Column Name + Field columnField = (Field) column.getJavaMember(); + byte[] indexColumnName = PropertyAccessorHelper.get(obj, columnField); + + ThriftRow tr = null; + if (indexColumnName != null && indexColumnName.length != 0 && rowKey != null) + { + // Construct Index Table Thrift Row + tr = new ThriftRow(); + tr.setColumnFamilyName(columnFamily); // Index column-family name + tr.setId(embeddedFieldName + Constants.INDEX_TABLE_ROW_KEY_DELIMITER + column.getName()); // Id + + SuperColumn thriftSuperColumn = new SuperColumn(); + thriftSuperColumn.setName(indexColumnName); + + Column thriftColumn = new Column(); + thriftColumn.setName(rowKey); + thriftColumn.setValue(ecValue.getBytes()); + thriftColumn.setTimestamp(System.currentTimeMillis()); + + thriftSuperColumn.addToColumns(thriftColumn); + + tr.addSuperColumn(thriftSuperColumn); + } + return tr; + } + + /** + * Gets the foreign keys from join table. + * + * @param + * the element type + * @param inverseJoinColumnName + * the inverse join column name + * @param columns + * the columns + * @param columnJavaType + * @return the foreign keys from join table + */ + public List getForeignKeysFromJoinTable(String inverseJoinColumnName, List columns, + Class columnJavaType) + { + List foreignKeys = new ArrayList(); + + if (columns == null || columns.isEmpty()) + { + return foreignKeys; + } + + for (Column c : columns) + { + try + { + // Thrift Column name + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, c.getName()); + + // Thrift Column Value + byte[] thriftColumnValue = c.getValue(); + if (null == thriftColumnValue) + { + continue; + } + + if (thriftColumnName != null && thriftColumnName.startsWith(inverseJoinColumnName)) + { + Object val = PropertyAccessorHelper.getObject(columnJavaType, thriftColumnValue); + foreignKeys.add(val); + } + } + catch (PropertyAccessException e) + { + continue; + } + + } + return foreignKeys; + } + + /** + * Populate entity. + * + * @param tr + * the tr + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @return the object + */ + public Object populateEntity(ThriftRow tr, EntityMetadata m, List relationNames, boolean isWrapReq) + { + Map relations = new HashMap(); + Object entity = null; + try + { + // entity =m.getEntityClazz().newInstance(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + boolean isCql3Enabled = clientBase.isCql3Enabled(m); + for (Column column : tr.getColumns()) + { + if (column != null) + { + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + if (CassandraConstants.CQL_KEY.equalsIgnoreCase(thriftColumnName) && tr.getId() == null) + { + entity = initialize(m, entity, null); + setId(m, entity, column.getValue(), isCql3Enabled); + } + else + { + entity = onColumn(column, m, entity, entityType, relationNames, isWrapReq, relations, + isCql3Enabled); + } + } + } + + // Add all super columns to entity + Collection embeddedCollection = null; + Field embeddedCollectionField = null; + + boolean mappingProcessed = false; + Map columnNameToFieldMap = new HashMap(); + Map superColumnNameToFieldMap = new HashMap(); + + for (SuperColumn superColumn : tr.getSuperColumns()) + { + if (superColumn != null) + { + entity = initialize(m, entity, tr.getId()); + + String scName = PropertyAccessorFactory.STRING.fromBytes(String.class, superColumn.getName()); + String scNamePrefix = null; + + // Map to hold property-name=>foreign-entity relations + Map> foreignKeysMap = new HashMap>(); + + // Get a name->field map for super-columns + if (!mappingProcessed) + { + MetadataUtils.populateColumnAndSuperColumnMaps(m, columnNameToFieldMap, + superColumnNameToFieldMap); + mappingProcessed = true; + } + + if (scName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) != -1) + { + scNamePrefix = MetadataUtils.getEmbeddedCollectionPrefix(scName); + embeddedCollectionField = superColumnNameToFieldMap.get(scNamePrefix); + + if (embeddedCollection == null) + { + embeddedCollection = MetadataUtils.getEmbeddedCollectionInstance(embeddedCollectionField); + } + + Object embeddedObject = MetadataUtils.getEmbeddedGenericObjectInstance(embeddedCollectionField); + + scrollOverSuperColumn(m, relationNames, isWrapReq, relations, entityType, superColumn, + embeddedObject, columnNameToFieldMap); + + Collection collection = PropertyAccessorHelper.getCollectionInstance(embeddedCollectionField); + collection.add(embeddedObject); + + PropertyAccessorHelper.set(entity, embeddedCollectionField, collection); + + embeddedCollection.add(embeddedObject); + + // Add this embedded object to cache + ElementCollectionCacheManager.getInstance().addElementCollectionCacheMapping(tr.getId(), + embeddedObject, scName); + + } + else + { + if (superColumnNameToFieldMap.containsKey(scName)) + { + Field field = superColumnNameToFieldMap.get(scName); + Object embeddedObj = field.getType().newInstance(); + // column + scrollOverSuperColumn(m, relationNames, isWrapReq, relations, entityType, superColumn, + embeddedObj, columnNameToFieldMap); + PropertyAccessorHelper.set(entity, field, embeddedObj); + } + else + { + scrollOverSuperColumn(m, relationNames, isWrapReq, relations, entityType, superColumn, + entity, isCql3Enabled); + } + + } + } + } + + mappingProcessed = false; + + for (CounterColumn counterColumn : tr.getCounterColumns()) + { + if (counterColumn != null) + { + entity = initialize(m, entity, tr.getId()); + onCounterColumn(counterColumn, m, entity, entityType, relationNames, isWrapReq, relations, + isCql3Enabled); + } + } + + for (CounterSuperColumn counterSuperColumn : tr.getCounterSuperColumns()) + { + if (counterSuperColumn != null) + { + entity = initialize(m, entity, tr.getId()); + String scName = PropertyAccessorFactory.STRING + .fromBytes(String.class, counterSuperColumn.getName()); + String scNamePrefix = null; + + // Map to hold property-name=>foreign-entity relations + Map> foreignKeysMap = new HashMap>(); + + // Get a name->field map for super-columns + // Get a name->field map for super-columns + if (!mappingProcessed) + { + MetadataUtils.populateColumnAndSuperColumnMaps(m, columnNameToFieldMap, + superColumnNameToFieldMap); + mappingProcessed = true; + } + + if (scName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) != -1) + { + scNamePrefix = MetadataUtils.getEmbeddedCollectionPrefix(scName); + embeddedCollectionField = superColumnNameToFieldMap.get(scNamePrefix); + + if (embeddedCollection == null) + { + embeddedCollection = MetadataUtils.getEmbeddedCollectionInstance(embeddedCollectionField); + } + + Object embeddedObject = MetadataUtils.getEmbeddedGenericObjectInstance(embeddedCollectionField); + + scrollOverCounterSuperColumn(m, relationNames, isWrapReq, relations, entityType, + counterSuperColumn, embeddedObject, columnNameToFieldMap); + embeddedCollection.add(embeddedObject); + + // Add this embedded object to cache + ElementCollectionCacheManager.getInstance().addElementCollectionCacheMapping(tr.getId(), + embeddedObject, scName); + } + else + { + if (superColumnNameToFieldMap.containsKey(scName)) + { + Field field = superColumnNameToFieldMap.get(scName); + Object embeddedObj = field.getType().newInstance(); + // column + scrollOverCounterSuperColumn(m, relationNames, isWrapReq, relations, entityType, + counterSuperColumn, embeddedObj, columnNameToFieldMap); + PropertyAccessorHelper.set(entity, field, embeddedObj); + } + else + { + scrollOverCounterSuperColumn(m, relationNames, isWrapReq, relations, entityType, + counterSuperColumn, entity, isCql3Enabled); + } + } + } + } + + if (embeddedCollection != null && !embeddedCollection.isEmpty()) + { + PropertyAccessorHelper.set(entity, embeddedCollectionField, embeddedCollection); + } + + } + catch (Exception e) + { + log.error("Eror while retrieving data, Caused by: .", e); + throw new PersistenceException(e); + } + + + if (entity != null && tr.getId() != null) + { + PropertyAccessorHelper.setId(entity, m, tr.getId()); + } + + return isWrapReq && relations != null && !relations.isEmpty() ? new EnhanceEntity(entity, + PropertyAccessorHelper.getId(entity, m), relations) : entity; + } + + private void setId(EntityMetadata m, Object entity, Object columnValue, boolean isCql3Enabled) + { + if (isCql3Enabled && !m.getType().equals(Type.SUPER_COLUMN_FAMILY)) + { + setFieldValueViaCQL(entity, columnValue, m.getIdAttribute()); + } + else + { + columnValue = PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), (byte[]) columnValue); + PropertyAccessorHelper.setId(entity, m, columnValue); + } + } + + /** + * Initialize. + * + * @param tr + * the tr + * @param m + * the m + * @param entity + * the entity + * @param tr + * @return the object + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + */ + private Object initialize(EntityMetadata m, Object entity, Object id) throws InstantiationException, + IllegalAccessException + { + if (entity == null) + { + entity = m.getEntityClazz().newInstance(); + if (id != null) + { + PropertyAccessorHelper.setId(entity, m, id); + } + } + + return entity; + } + + /** + * Scroll over super column. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param entityType + * the entity type + * @param superColumn + * the super column + * @param embeddedObject + * the embedded object + * @param isCql3Enabled + * @throws IllegalAccessException + * @throws InstantiationException + */ + private void scrollOverSuperColumn(EntityMetadata m, List relationNames, boolean isWrapReq, + Map relations, EntityType entityType, SuperColumn superColumn, Object embeddedObject, + boolean isCql3Enabled) throws InstantiationException, IllegalAccessException + { + for (Column column : superColumn.getColumns()) + { + embeddedObject = onColumn(column, m, embeddedObject, entityType, relationNames, isWrapReq, relations, + isCql3Enabled); + } + } + + /** + * Scroll over counter super column. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param entityType + * the entity type + * @param superColumn + * the super column + * @param embeddedObject + * the embedded object + * @throws IllegalAccessException + * @throws InstantiationException + */ + private void scrollOverCounterSuperColumn(EntityMetadata m, List relationNames, boolean isWrapReq, + Map relations, EntityType entityType, CounterSuperColumn superColumn, + Object embeddedObject, boolean isCql3Enabled) throws InstantiationException, IllegalAccessException + { + for (CounterColumn column : superColumn.getColumns()) + { + onCounterColumn(column, m, embeddedObject, entityType, relationNames, isWrapReq, relations, isCql3Enabled); + } + } + + /** + * Scroll over counter super column. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param entityType + * the entity type + * @param superColumn + * the super column + * @param embeddedObject + * the embedded object + * @param superColumnFieldMap + * the super column field map + */ + private void scrollOverCounterSuperColumn(EntityMetadata m, List relationNames, boolean isWrapReq, + Map relations, EntityType entityType, CounterSuperColumn superColumn, + Object embeddedObject, Map superColumnFieldMap) + { + for (CounterColumn column : superColumn.getColumns()) + { + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + String thriftColumnValue = new Long(column.getValue()).toString(); + PropertyAccessorHelper.set(embeddedObject, superColumnFieldMap.get(thriftColumnName), thriftColumnValue); + } + } + + /** + * Scroll over super column. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param entityType + * the entity type + * @param superColumn + * the super column + * @param embeddedObject + * the embedded object + * @param superColumnFieldMap + * the super column field map + */ + private void scrollOverSuperColumn(EntityMetadata m, List relationNames, boolean isWrapReq, + Map relations, EntityType entityType, SuperColumn superColumn, Object embeddedObject, + Map superColumnFieldMap) + { + for (Column column : superColumn.getColumns()) + { + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + byte[] thriftColumnValue = column.getValue(); + PropertyAccessorHelper.set(embeddedObject, superColumnFieldMap.get(thriftColumnName), thriftColumnValue); + } + } + + /** + * On column. + * + * @param column + * the column + * @param m + * the m + * @param entity + * the entity + * @param entityType + * the entity type + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @param isCql3Enabled + * @throws IllegalAccessException + * @throws InstantiationException + */ + private Object onColumn(Column column, EntityMetadata m, Object entity, EntityType entityType, + List relationNames, boolean isWrapReq, Map relations, boolean isCql3Enabled) + throws InstantiationException, IllegalAccessException + { + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + byte[] thriftColumnValue = column.getValue(); + if (m.isCounterColumnType()) + { + LongAccessor accessor = new LongAccessor(); + Long value = accessor.fromBytes(Long.class, column.getValue()); + return populateViaThrift(m, entity, entityType, relationNames, relations, thriftColumnName, + value.toString(), isCql3Enabled); + } + return populateViaThrift(m, entity, entityType, relationNames, relations, thriftColumnName, thriftColumnValue, + isCql3Enabled); + } + + /** + * On counter column. + * + * @param column + * the column + * @param m + * the m + * @param entity + * the entity + * @param entityType + * the entity type + * @param relationNames + * the relation names + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @throws IllegalAccessException + * @throws InstantiationException + */ + private void onCounterColumn(CounterColumn column, EntityMetadata m, Object entity, EntityType entityType, + List relationNames, boolean isWrapReq, Map relations, boolean isCql3Enabled) + throws InstantiationException, IllegalAccessException + { + String thriftColumnName = PropertyAccessorFactory.STRING.fromBytes(String.class, column.getName()); + String thriftColumnValue = new Long(column.getValue()).toString(); + populateViaThrift(m, entity, entityType, relationNames, relations, thriftColumnName, thriftColumnValue, + isCql3Enabled); + } + + /** + * Populate via thrift. + * + * @param m + * the m + * @param entity + * the entity + * @param entityType + * the entity type + * @param relationNames + * the relation names + * @param relations + * the relations + * @param thriftColumnName + * the thrift column name + * @param thriftColumnValue + * the thrift column value + * @param isCql3Enabled + * @throws IllegalAccessException + * @throws InstantiationException + */ + private Object populateViaThrift(EntityMetadata m, Object entity, EntityType entityType, + List relationNames, Map relations, String thriftColumnName, + Object thriftColumnValue, boolean isCql3Enabled) throws InstantiationException, IllegalAccessException + { + if (relationNames == null || !relationNames.contains(thriftColumnName)) + { + if (thriftColumnValue != null) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetamodel(m.getPersistenceUnit()); + String fieldName = m.getFieldName(thriftColumnName); + Attribute attribute = fieldName != null ? entityType.getAttribute(fieldName) : null; + + if (attribute != null) + { + entity = initialize(m, entity, null); + if (!attribute.isAssociation()) + { + String idColumnName = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + if (!metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType()) + && thriftColumnName.equals(idColumnName)) + { + setId(m, entity, thriftColumnValue, isCql3Enabled); + PropertyAccessorHelper.setId(entity, m, (byte[]) thriftColumnValue); + } + if (isCql3Enabled && !m.getType().equals(Type.SUPER_COLUMN_FAMILY) && !m.isCounterColumnType()) + { + setFieldValueViaCQL(entity, thriftColumnValue, attribute); + } + else + { + setFieldValue(entity, thriftColumnValue, attribute); + } + } + } + else + { + entity = populateCompositeId(m, entity, thriftColumnName, thriftColumnValue, metaModel); + } + } + } + else + { + // populate relation. + if (relationNames != null && relationNames.contains(thriftColumnName) && thriftColumnValue != null) + { + String fieldName = m.getFieldName(thriftColumnName); + Attribute attribute = fieldName != null ? entityType.getAttribute(fieldName) : null; + + EntityMetadata relationMetadata = KunderaMetadataManager.getEntityMetadata(attribute.getJavaType()); + Object value; + if (isCql3Enabled && !m.getType().equals(Type.SUPER_COLUMN_FAMILY)) + { + value = getFieldValueViaCQL(thriftColumnValue, relationMetadata.getIdAttribute()); + } + else + { + value = PropertyAccessorHelper.getObject(relationMetadata.getIdAttribute().getJavaType(), + (byte[]) thriftColumnValue); + } + relations.put(thriftColumnName, value); + + if (entity == null) + { + entity = initialize(m, entity, null); + } + // prepare EnhanceEntity and return it + } + + } + return entity; + } + + private Object populateCompositeId(EntityMetadata m, Object entity, String thriftColumnName, + Object thriftColumnValue, MetamodelImpl metaModel) throws InstantiationException, IllegalAccessException + { + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + EmbeddableType compoundKey = metaModel.embeddable(m.getIdAttribute().getBindableJavaType()); + Object compoundKeyObject = null; + try + { + // for() + Set attributes = compoundKey.getAttributes(); + + for (Attribute compoundAttribute : attributes) + { + if (((AbstractAttribute) compoundAttribute).getJPAColumnName().equals(thriftColumnName)) + { + entity = initialize(m, entity, null); + + compoundKeyObject = compoundKeyObject == null ? getCompoundKey(m, entity) : compoundKeyObject; + + setFieldValueViaCQL(compoundKeyObject, thriftColumnValue, compoundAttribute); + PropertyAccessorHelper.set(entity, (Field) m.getIdAttribute().getJavaMember(), + compoundKeyObject); + break; + } + } + // setFieldValue(entity, , + // attribute) + + } + catch (IllegalArgumentException iaex) + { + // ignore as it might not repesented within entity. + // No + // need for any logger message + } + catch (Exception e) + { + log.error("Error while retrieving data, Caused by: .", e); + throw new PersistenceException(e); + } + } + return entity; + } + + private Object getCompoundKey(EntityMetadata m, Object entity) throws InstantiationException, + IllegalAccessException + { + Object compoundKeyObject = null; + if (entity != null) + { + compoundKeyObject = PropertyAccessorHelper.getObject(entity, (Field) m.getIdAttribute().getJavaMember()); + if (compoundKeyObject == null) + { + compoundKeyObject = m.getIdAttribute().getBindableJavaType().newInstance(); + } + } + + return compoundKeyObject; + } + + private void setFieldValue(Object entity, Object thriftColumnValue, Attribute attribute) + { + if (attribute != null) + { + try + { + if (thriftColumnValue.getClass().isAssignableFrom(String.class)) + { + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), (String) thriftColumnValue); + } + else + { + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), (byte[]) thriftColumnValue); + } + } + catch (PropertyAccessException pae) + { + log.warn("Error while setting field value, Caused by: .", pae); + } + } + } + + private void setFieldValueViaCQL(Object entity, Object thriftColumnValue, Attribute attribute) + { + if (attribute != null) + { + + try + { + if(attribute.isCollection()) + { + setCollectionValue(entity, thriftColumnValue, attribute); + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(String.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(char.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(Character.class)) + { + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), new String( + (byte[]) thriftColumnValue)); + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(short.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(Short.class)) + { + IntegerAccessor accessor = new IntegerAccessor(); + Integer value = accessor.fromBytes(short.class, (byte[]) thriftColumnValue); + // String value = + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), String.valueOf(value)); + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(byte.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(Byte.class)) + { + IntegerAccessor accessor = new IntegerAccessor(); + Integer value = accessor.fromBytes(byte.class, (byte[]) thriftColumnValue); + // String value = + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), String.valueOf(value)); + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(BigDecimal.class)) + { + DoubleAccessor accessor = new DoubleAccessor(); + Double value = accessor.fromBytes(Double.class, (byte[]) thriftColumnValue); + // String value = + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), String.valueOf(value)); + } + else + { + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), (byte[]) thriftColumnValue); + } + } + catch (PropertyAccessException pae) + { + log.warn("Error while setting field{} value via CQL, Caused by: .", attribute.getName(),pae); + } + } + } + + /** + * Populates collection field(s) into entity + * @param entity + * @param thriftColumnValue + * @param attribute + */ + private void setCollectionValue(Object entity, Object thriftColumnValue, Attribute attribute) + { + try + { + if (Collection.class.isAssignableFrom(((Field) attribute.getJavaMember()).getType())) + { + + Collection outputCollection = null; + ByteBuffer valueByteBuffer = ByteBuffer.wrap((byte[]) thriftColumnValue); + Class genericClass = PropertyAccessorHelper.getGenericClass((Field) attribute.getJavaMember()); + Class valueValidationClass = CassandraValidationClassMapper.getValidationClassInstance(genericClass, + true); + Object valueClassInstance = valueValidationClass.getDeclaredField("instance").get(null); + + if (((Field) attribute.getJavaMember()).getType().isAssignableFrom(List.class)) + { + ListType listType = ListType.getInstance((AbstractType) valueClassInstance); + outputCollection = new ArrayList(); + outputCollection.addAll(listType.compose(valueByteBuffer)); + } + + else if (((Field) attribute.getJavaMember()).getType().isAssignableFrom(Set.class)) + { + SetType setType = SetType.getInstance((AbstractType) valueClassInstance); + outputCollection = new HashSet(); + outputCollection.addAll(setType.compose(valueByteBuffer)); + } + + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), outputCollection); + } + + else if (((Field) attribute.getJavaMember()).getType().isAssignableFrom(Map.class)) + { + ByteBuffer valueByteBuffer = ByteBuffer.wrap((byte[]) thriftColumnValue); + List> mapGenericClasses = PropertyAccessorHelper.getGenericClasses((Field) attribute + .getJavaMember()); + + Class keyClass = CassandraValidationClassMapper.getValidationClassInstance(mapGenericClasses.get(0), + true); + Class valueClass = CassandraValidationClassMapper.getValidationClassInstance(mapGenericClasses.get(1), + true); + + Object keyClassInstance = keyClass.getDeclaredField("instance").get(null); + Object valueClassInstance = valueClass.getDeclaredField("instance").get(null); + + MapType mapType = MapType.getInstance((AbstractType) keyClassInstance, + (AbstractType) valueClassInstance); + + Map outputMap = new HashMap(); + outputMap.putAll(mapType.compose(valueByteBuffer)); + PropertyAccessorHelper.set(entity, (Field) attribute.getJavaMember(), outputMap); + + } + } + catch (Exception e) + { + log.error("Error while setting field{} value via CQL, Caused by: .", attribute.getName(), e); + throw new PersistenceException(e); + } + } + + private Object getFieldValueViaCQL(Object thriftColumnValue, Attribute attribute) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor((Field) attribute.getJavaMember()); + Object objValue; + try + { + if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(String.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(char.class) + || ((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(Character.class)) + { + + objValue = accessor.fromString(((AbstractAttribute) attribute).getBindableJavaType(), new String( + (byte[]) thriftColumnValue)); + return objValue; + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(short.class)) + { + IntegerAccessor intAccessor = new IntegerAccessor(); + Integer value = intAccessor.fromBytes(short.class, (byte[]) thriftColumnValue); + objValue = accessor.fromString(((AbstractAttribute) attribute).getBindableJavaType(), + String.valueOf(value)); + return objValue; + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(byte.class)) + { + IntegerAccessor intAccessor = new IntegerAccessor(); + Integer value = intAccessor.fromBytes(byte.class, (byte[]) thriftColumnValue); + objValue = accessor.fromString(((AbstractAttribute) attribute).getBindableJavaType(), + String.valueOf(value)); + return objValue; + } + else if (((AbstractAttribute) attribute).getBindableJavaType().isAssignableFrom(BigDecimal.class)) + { + DoubleAccessor doubleAccessor = new DoubleAccessor(); + Double value = doubleAccessor.fromBytes(Double.class, (byte[]) thriftColumnValue); + return value; + } + else + { + objValue = accessor.fromBytes(((AbstractAttribute) attribute).getBindableJavaType(), + (byte[]) thriftColumnValue); + return objValue; + } + } + catch (PropertyAccessException pae) + { + log.warn("Error while setting field{} value via CQL, Caused by: .", attribute.getName(),pae); + } + return null; + } + + /** + * On column or super column thrift row. + * @param tr + * the tr + * @param m + * the m + * @param e + * the e + * @param id + * the id + * @param timestamp + * the timestamp2 + * @param columnTTLs TODO + */ + + private void onColumnOrSuperColumnThriftRow(ThriftRow tr, EntityMetadata m, Object e, Object id, long timestamp, Object columnTTLs) + { + + // Iterate through Super columns + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + Set attributes = entityType.getAttributes(); + for (Attribute attribute : attributes) + { + if (!attribute.getName().equals(m.getIdAttribute().getName()) && !attribute.isAssociation()) + { + Field field = (Field) ((Attribute) attribute).getJavaMember(); + byte[] name = PropertyAccessorFactory.STRING + .toBytes(((AbstractAttribute) attribute).getJPAColumnName()); + + // if attribute is embeddable. + if (metaModel.isEmbeddable(attribute.isCollection() ? ((PluralAttribute) attribute) + .getBindableJavaType() : attribute.getJavaType())) + { + onEmbeddable(timestamp, tr, m, e, id, attribute); + } + else + { + Object value = getColumnValue(m, e, field); + + if (m.getType().equals(Type.SUPER_COLUMN_FAMILY)) + { + + prepareSuperColumn(tr, m, value, name, timestamp); + } + else + { + int ttl = getTTLForColumn(columnTTLs, attribute); + prepareColumn(tr, m, value, name, timestamp, ttl); + } + } + } + } + + } + + /** + * Determined TTL for a given column + */ + private int getTTLForColumn(Object columnTTLs, Attribute attribute) { + Integer ttl = null; + if(columnTTLs != null) + { + if(columnTTLs instanceof Map) + { + ttl = (Integer)(columnTTLs == null ? 0 : ((Map)columnTTLs).get(((AbstractAttribute) attribute).getJPAColumnName())); + } + else if(columnTTLs instanceof Integer) + { + ttl = (Integer) columnTTLs; + } + } + return ttl == null ? 0 : ttl; + } + + private Object getColumnValue(EntityMetadata m, Object e, Field field) + { + Object value; + if (!m.isCounterColumnType()) + { + value = PropertyAccessorHelper.get(e, field); + } + else + { + value = PropertyAccessorHelper.getString(e, field); + } + return value; + } + + /** + * Prepare column. + * + * @param tr + * the tr + * @param m + * the m + * @param value + * the value + * @param name + * the name + * @param timestamp + * the timestamp + * @param ttl TODO + */ + private void prepareColumn(ThriftRow tr, EntityMetadata m, Object value, byte[] name, long timestamp, int ttl) + { + if (value != null) + { + if (m.isCounterColumnType()) + { + CounterColumn counterColumn = prepareCounterColumn((String) value, name); + tr.addCounterColumn(counterColumn); + } + else + { + Column column = prepareColumn((byte[]) value, name, timestamp, ttl); + tr.addColumn(column); + } + } + + } + + /** + * Prepare super column. + * + * @param tr + * the tr + * @param m + * the m + * @param value + * the value + * @param name + * the name + * @param timestamp + * the timestamp + */ + private void prepareSuperColumn(ThriftRow tr, EntityMetadata m, Object value, byte[] name, long timestamp) + { + if (value != null) + { + if (m.isCounterColumnType()) + { + CounterSuperColumn counterSuper = new CounterSuperColumn(); + counterSuper.setName(name); + CounterColumn counterColumn = prepareCounterColumn((String) value, name); + List subCounterColumn = new ArrayList(); + subCounterColumn.add(counterColumn); + counterSuper.setColumns(subCounterColumn); + tr.addCounterSuperColumn(counterSuper); + } + else + { + SuperColumn superCol = new SuperColumn(); + superCol.setName(name); + Column column = prepareColumn((byte[]) value, name, timestamp, 0); + List subColumn = new ArrayList(); + subColumn.add(column); + superCol.setColumns(subColumn); + tr.addSuperColumn(superCol); + + } + } + } + + /** + * Prepare column. + * + * @param value + * the value + * @param name + * the name + * @param timestamp + * the timestamp + * @param ttl TODO + * @return the column + */ + private Column prepareColumn(byte[] value, byte[] name, long timestamp, int ttl) + { + Column column = new Column(); + column.setName(name); + column.setValue(value); + column.setTimestamp(timestamp); + if(ttl != 0) column.setTtl(ttl); + return column; + } + + /** + * Prepare counter column. + * + * @param value + * the value + * @param name + * the name + * @return the counter column + */ + private CounterColumn prepareCounterColumn(String value, byte[] name) + { + CounterColumn counterColumn = new CounterColumn(); + counterColumn.setName(name); + LongAccessor accessor = new LongAccessor(); + counterColumn.setValue(accessor.fromString(LongAccessor.class, value)); + return counterColumn; + } + + /** + * + * On embeddable. + * + * @param timestamp2 + * the timestamp2 + * @param tr + * the tr + * @param m + * the m + * @param e + * the e + * @param id + * the id + * @param embeddableAttrib + * the embeddable attrib + */ + private void onEmbeddable(long timestamp2, ThriftRow tr, EntityMetadata m, Object e, Object id, + Attribute embeddableAttrib) + { + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + // Map embeddables = + // metaModel.getEmbeddables(m.getEntityClazz()); + + EmbeddableType superColumn = metaModel.embeddable(((AbstractAttribute) embeddableAttrib).getBindableJavaType()); + + // for (String key : embeddables.keySet()) + // { + + // EmbeddableType superColumn = embeddables.get(key); + Field superColumnField = (Field) embeddableAttrib.getJavaMember(); + Object superColumnObject = PropertyAccessorHelper.getObject(e, superColumnField); + + // If Embedded object is a Collection, there will be variable number + // of super columns one for each object in collection. + // Key for each super column will be of the format "# + + // On the other hand, if embedded object is not a Collection, it + // would simply be embedded as ONE super column. + String superColumnName = null; + /* + * if (superColumnObject == null) { continue; } + */ + if (superColumnObject != null && superColumnObject instanceof Collection) + { + + ElementCollectionCacheManager ecCacheHandler = ElementCollectionCacheManager.getInstance(); + + // Check whether it's first time insert or updation + if (ecCacheHandler.isCacheEmpty()) + { // First time insert + int count = 0; + for (Object obj : (Collection) superColumnObject) + { + // superColumnName = superColumn.getName() + + // Constants.EMBEDDED_COLUMN_NAME_DELIMITER + count; + superColumnName = ((AbstractAttribute) embeddableAttrib).getJPAColumnName() + + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + count; + + if (m.isCounterColumnType()) + { + CounterSuperColumn thriftSuperColumn = buildThriftCounterSuperColumn(superColumnName, + superColumn, obj); + tr.addCounterSuperColumn(thriftSuperColumn); + } + else + { + SuperColumn thriftSuperColumn = buildThriftSuperColumn(superColumnName, timestamp2, + superColumn, obj); + tr.addSuperColumn(thriftSuperColumn); + } + ecCacheHandler.addElementCollectionCacheMapping(id, obj, superColumnName); + count++; + } + } + else + { + // Updation, Check whether this object is already in cache, + // which means we already have a super column + // Otherwise we need to generate a fresh embedded column + // name + int lastEmbeddedObjectCount = ecCacheHandler.getLastElementCollectionObjectCount(id); + for (Object obj : (Collection) superColumnObject) + { + superColumnName = ecCacheHandler.getElementCollectionObjectName(id, obj); + if (superColumnName == null) + { // Fresh row + superColumnName = ((AbstractAttribute) embeddableAttrib).getJPAColumnName() + + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + (++lastEmbeddedObjectCount); + } + buildThriftSuperColumn(timestamp2, tr, m, id, superColumn, superColumnName, obj); + ecCacheHandler.addElementCollectionCacheMapping(id, obj, superColumnName); + } + } + + } + else if (superColumnObject != null) + { + superColumnName = ((AbstractAttribute) embeddableAttrib).getJPAColumnName(); + buildThriftSuperColumn(timestamp2, tr, m, id, superColumn, superColumnName, superColumnObject); + } + } + + /** + * Builds the thrift super column. + * + * @param timestamp2 + * the timestamp2 + * @param tr + * the tr + * @param m + * the m + * @param id + * the id + * @param superColumn + * the super column + * @param superColumnName + * the super column name + * @param obj + * the obj + */ + private void buildThriftSuperColumn(long timestamp2, ThriftRow tr, EntityMetadata m, Object id, + EmbeddableType superColumn, String superColumnName, Object obj) + { + if (m.isCounterColumnType()) + { + CounterSuperColumn thriftSuperColumn = buildThriftCounterSuperColumn(superColumnName, superColumn, obj); + tr.addCounterSuperColumn(thriftSuperColumn); + } + else + { + SuperColumn thriftSuperColumn = buildThriftSuperColumn(superColumnName, timestamp2, superColumn, obj); + tr.addSuperColumn(thriftSuperColumn); + } + } + + /** + * Builds the thrift counter super column. + * + * @param superColumnName + * the super column name + * @param superColumn + * the super column + * @param counterSuperColumnObject + * the counter super column object + * @return the counter super column + */ + private CounterSuperColumn buildThriftCounterSuperColumn(String superColumnName, EmbeddableType superColumn, + Object counterSuperColumnObject) + { + + Iterator iter = superColumn.getAttributes().iterator(); + + List thriftColumns = new ArrayList(); + + while (iter.hasNext()) + { + Attribute column = iter.next(); + Field field = (Field) column.getJavaMember(); + String name = ((AbstractAttribute) column).getJPAColumnName(); + String value = null; + try + { + value = PropertyAccessorHelper.getString(counterSuperColumnObject, field); + + } + catch (PropertyAccessException exp) + { + // This is an entity column to be persisted in a super column + // family. It will be stored as a super column that would + // have just one column with the same name + if (log.isInfoEnabled()) + { + log.info(exp.getMessage() + + ". Possible case of entity column in a super column family. Will be treated as a super column."); + } + + value = counterSuperColumnObject.toString(); + } + if (null != value) + { + try + { + CounterColumn thriftColumn = new CounterColumn(); + thriftColumn.setName(PropertyAccessorFactory.STRING.toBytes(name)); + thriftColumn.setValue(Long.parseLong(value)); + thriftColumns.add(thriftColumn); + } + catch (NumberFormatException nfe) + { + log.error("For counter column arguments should be numeric type, Caused by: .", nfe); + throw new KunderaException(nfe); + } + } + } + CounterSuperColumn thriftSuperColumn = new CounterSuperColumn(); + thriftSuperColumn.setName(PropertyAccessorFactory.STRING.toBytes(superColumnName)); + thriftSuperColumn.setColumns(thriftColumns); + + return thriftSuperColumn; + + } + + /** + * Builds the thrift super column. + * + * @param superColumnName + * the super column name + * @param timestamp + * the timestamp + * @param superColumn + * the super column + * @param superColumnObject + * the super column object + * @return the super column + * @throws PropertyAccessException + * the property access exception + */ + private SuperColumn buildThriftSuperColumn(String superColumnName, long timestamp, EmbeddableType superColumn, + Object superColumnObject) throws PropertyAccessException + { + List thriftColumns = new ArrayList(); + + Iterator iter = superColumn.getAttributes().iterator(); + + while (iter.hasNext()) + { + AbstractAttribute column = (AbstractAttribute) iter.next(); + + // + // for (com.impetus.kundera.metadata.model.Column column : + // superColumn.getColumns()) + // { + Field field = (Field) column.getJavaMember(); + String name = column.getJPAColumnName(); + byte[] value = null; + try + { + value = PropertyAccessorHelper.get(superColumnObject, field); + + } + catch (PropertyAccessException exp) + { + // This is an entity column to be persisted in a super column + // family. It will be stored as a super column that would + // have just one column with the same name + if (log.isInfoEnabled()) + { + log.info(exp.getMessage() + + ". Possible case of entity column in a super column family. Will be treated as a super column."); + } + value = superColumnObject.toString().getBytes(); + } + if (null != value) + { + Column thriftColumn = new Column(); + thriftColumn.setName(PropertyAccessorFactory.STRING.toBytes(name)); + thriftColumn.setValue(value); + thriftColumn.setTimestamp(timestamp); + thriftColumns.add(thriftColumn); + } + } + SuperColumn thriftSuperColumn = new SuperColumn(); + thriftSuperColumn.setName(PropertyAccessorFactory.STRING.toBytes(superColumnName)); + thriftSuperColumn.setColumns(thriftColumns); + + return thriftSuperColumn; + } + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandler.java new file mode 100644 index 000000000..f1fc8dfa2 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandler.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.datahandler; + +/** + * Defines low level database methods for Cassandra + * + * @author amresh.singh + */ +public interface DataHandler +{ + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandlerBase.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandlerBase.java new file mode 100644 index 000000000..983b57e62 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/datahandler/DataHandlerBase.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.datahandler; + +/** + * Base class for all Cassandra Data Handlers + * + * @author amresh.singh + */ +public abstract class DataHandlerBase +{ + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/CassandraIndexHelper.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/CassandraIndexHelper.java new file mode 100644 index 000000000..6a817fe6b --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/CassandraIndexHelper.java @@ -0,0 +1,79 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.index; + +import org.apache.cassandra.thrift.IndexType; + +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.kundera.Constants; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Provides functionalities related to indexing in cassandra + * + * @author amresh.singh + */ +public class CassandraIndexHelper +{ + /** + * Generates inverted index table name for a given table + * + * @param tableName + * @return + */ + public static String getInvertedIndexTableName(String tableName) + { + return tableName + Constants.INDEX_TABLE_SUFFIX; + } + + /** + * Checks whether Inverted indexing is applicable for a given entity whose + * metadata is passed as parameter + * + * @param m + * @return + */ + public static boolean isInvertedIndexingApplicable(EntityMetadata m, boolean useSecondryIndex) + { + boolean invertedIndexingApplicable = useSecondryIndex + && CassandraPropertyReader.csmd.isInvertedIndexingEnabled(m.getSchema()) + && m.getType().isSuperColumnFamilyMetadata() && !m.isCounterColumnType(); + + return invertedIndexingApplicable; + } + + /** + * @param indexType + * @return + */ + public static IndexType getIndexType(String indexType) + { + if (indexType != null) + { + if (indexType.equals(IndexType.KEYS.name())) + { + return IndexType.KEYS; + } + else if (indexType.equals(IndexType.CUSTOM.name())) + { + return IndexType.CUSTOM; + } + } + return IndexType.KEYS; + } + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandler.java new file mode 100644 index 000000000..7e326eced --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandler.java @@ -0,0 +1,70 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.index; + +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexClause; + +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * This interface defines methods for operation on inverted indexes + * + * @author amresh.singh + */ +public interface InvertedIndexHandler +{ + + /** + * Writes a record into inverted index table. + * + * @param node + * @param entityMetadata + * @param persistenceUnit + * @param consistencyLevel + * @param cdHandler + */ + void write(Node node, EntityMetadata entityMetadata, String persistenceUnit, ConsistencyLevel consistencyLevel, + CassandraDataHandler cdHandler); + + /** + * Searches records from Inverted index table. + * + * @param m + * @param filterClauseQueue + * @param persistenceUnit + * @param consistencyLevel + * @return + */ + List search(EntityMetadata m, String persistenceUnit, ConsistencyLevel consistencyLevel, + Map> indexClauseMap); + + /** + * Deletes a record from inverted index table. + * + * @param entity + * @param metadata + * @param consistencyLevel + */ + void delete(Object entity, EntityMetadata metadata, ConsistencyLevel consistencyLevel); + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandlerBase.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandlerBase.java new file mode 100644 index 000000000..f651bb434 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/index/InvertedIndexHandlerBase.java @@ -0,0 +1,316 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.index; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.cassandra.thrift.SuperColumn; +import org.scale7.cassandra.pelops.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.DefaultSingularAttribute; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.query.QueryHandlerException; + +/** + * Base class for + * + * @author amresh.singh + */ +public abstract class InvertedIndexHandlerBase +{ + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(InvertedIndexHandlerBase.class); + + protected boolean useSecondryIndex; + + public List search(EntityMetadata m, String persistenceUnit, ConsistencyLevel consistencyLevel, + Map> indexClauseMap) + { + String columnFamilyName = m.getTableName() + Constants.INDEX_TABLE_SUFFIX; + + List searchResults = new ArrayList(); + + boolean isRowKeyQuery = indexClauseMap.keySet().iterator().next(); + + for (IndexClause o : indexClauseMap.get(isRowKeyQuery)) + { + for (IndexExpression expression : o.getExpressions()) + { + searchAndAddToResults(m, persistenceUnit, consistencyLevel, columnFamilyName, searchResults, + expression, isRowKeyQuery); + } + + } + return searchResults; + } + + /** + * Searches into inverted index based on expression and adds + * search result to searchResults + */ + private void searchAndAddToResults(EntityMetadata m, String persistenceUnit, ConsistencyLevel consistencyLevel, + String columnFamilyName, List searchResults, IndexExpression expression, + boolean isRowKeyQuery) + { + SearchResult searchResult = new SearchResult(); + + String rowKey = Bytes.toUTF8(expression.getColumn_name()); + byte[] superColumnName = expression.getValue(); + String superColumnNameStr = Bytes.toUTF8(expression.getValue()); + Object pk = PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), superColumnName); + IndexOperator condition = expression.getOp(); + + if (log.isInfoEnabled()) + { + log.info("RowKey: {} ; Super column Name: {} on condition.",rowKey,superColumnNameStr, condition); + } + + // TODO: Second check unnecessary but unavoidable as filter clause + // property is incorrectly passed as column name + + // Search based on Primary key + if (isRowKeyQuery + && (rowKey.equals(m.getIdAttribute().getName()) || rowKey.equals(((DefaultSingularAttribute) m + .getIdAttribute()).getJPAColumnName()))) + { + if (searchResults.isEmpty()) + { + searchResult.setPrimaryKey(pk); + searchResults.add(searchResult); + } + else + { + SearchResult existing = searchResults.get(0); + if (existing.getPrimaryKey() != null && existing.getPrimaryKey().equals(superColumnNameStr)) + { + searchResults.add(searchResult); + } + else + { + searchResults.remove(0); + } + } + } + else + { + // Search results in the form of thrift super columns + List thriftSuperColumns = new ArrayList(); + + switch (condition) + { + // EQUAL Operator + case EQ: + SuperColumn thriftSuperColumn = getSuperColumnForRow(consistencyLevel, columnFamilyName, rowKey, + superColumnName, persistenceUnit); + + if (thriftSuperColumn != null) + thriftSuperColumns.add(thriftSuperColumn); + break; + + // LIKE operation not available + /* + * case LIKE: searchColumnsInRange(columnFamilyName, + * consistencyLevel, persistenceUnit, rowKey, columnName, + * thriftColumns, columnName.getBytes(), new byte[0]); break; + */ + + // Greater than operator + case GT: + searchSuperColumnsInRange(columnFamilyName, consistencyLevel, persistenceUnit, rowKey, superColumnName, + thriftSuperColumns, superColumnName, new byte[0]); + break; + // Less than Operator + case LT: + searchSuperColumnsInRange(columnFamilyName, consistencyLevel, persistenceUnit, rowKey, superColumnName, + thriftSuperColumns, new byte[0], superColumnName); + break; + // Greater than-equals to operator + case GTE: + searchSuperColumnsInRange(columnFamilyName, consistencyLevel, persistenceUnit, rowKey, superColumnName, + thriftSuperColumns, superColumnName, new byte[0]); + break; + // Less than equal to operator + case LTE: + searchSuperColumnsInRange(columnFamilyName, consistencyLevel, persistenceUnit, rowKey, superColumnName, + thriftSuperColumns, new byte[0], superColumnName); + break; + + default: + throw new QueryHandlerException(condition + + " comparison operator not supported currently for Cassandra Inverted Index."); + + } + + // Construct search results out of these thrift columns + for (SuperColumn thriftSuperColumn : thriftSuperColumns) + { + + for (Column column : thriftSuperColumn.getColumns()) + { + byte[] columnName = column.getName(); + searchResult.setPrimaryKey(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), + columnName)); + byte[] columnValue = column.getValue(); + String ecValue = Bytes.toUTF8(columnValue); + + if (ecValue != null && !"".equals(ecValue.trim())) + { + searchResult.setEmbeddedColumnName(rowKey.substring(0, + rowKey.indexOf(Constants.INDEX_TABLE_ROW_KEY_DELIMITER))); + searchResult.addEmbeddedColumnValue(ecValue); + } + } + + if (searchResults.isEmpty()) + { + searchResults.add(searchResult); + } + else + { + SearchResult existing = searchResults.get(0); + if (existing.getPrimaryKey() != null + && existing.getPrimaryKey().equals(searchResult.getPrimaryKey())) + { + searchResults.add(searchResult); + } + else + { + searchResults.remove(0); + } + } + + } + } + } + + public void delete(Object entity, EntityMetadata metadata, ConsistencyLevel consistencyLevel) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + if (CassandraIndexHelper.isInvertedIndexingApplicable(metadata, useSecondryIndex)) + { + + String indexColumnFamily = CassandraIndexHelper.getInvertedIndexTableName(metadata.getTableName()); + Map embeddables = metaModel.getEmbeddables(metadata.getEntityClazz()); + // for (EmbeddedColumn embeddedColumn : + // metadata.getEmbeddedColumnsAsList()) + EntityType entityType = metaModel.entity(metadata.getEntityClazz()); + + byte[] columnName = PropertyAccessorHelper.get(entity, (Field) metadata.getIdAttribute().getJavaMember()); + + for (String fieldName : embeddables.keySet()) + { + EmbeddableType embeddedColumn = embeddables.get(fieldName); + Attribute embeddedAttribute = entityType.getAttribute(fieldName); + // Object embeddedObject = + // PropertyAccessorHelper.getObject(entity, + // embeddedColumn.getField()); + Object embeddedObject = PropertyAccessorHelper.getObject(entity, + (Field) embeddedAttribute.getJavaMember()); + + if (embeddedObject != null) + { + if (embeddedObject instanceof Collection) + { + for (Object obj : (Collection) embeddedObject) + { + Iterator iter = embeddedColumn.getAttributes().iterator(); + while (iter.hasNext()) + { + Attribute attrib = iter.next(); + String rowKey = embeddedAttribute.getName() + Constants.INDEX_TABLE_ROW_KEY_DELIMITER + + attrib.getName(); + byte[] superColumnName = PropertyAccessorHelper + .get(obj, (Field) attrib.getJavaMember()); + if (superColumnName != null) + { + deleteColumn(indexColumnFamily, rowKey, superColumnName, + metadata.getPersistenceUnit(), consistencyLevel, columnName); + } + } + } + } + else + { + + Iterator iter = embeddedColumn.getAttributes().iterator(); + while (iter.hasNext()) + { + Attribute attrib = iter.next(); + String rowKey = embeddedAttribute.getName() + Constants.INDEX_TABLE_ROW_KEY_DELIMITER + + attrib.getName(); + byte[] superColumnName = PropertyAccessorHelper.get(embeddedObject, + (Field) attrib.getJavaMember()); + if (superColumnName != null) + { + deleteColumn(indexColumnFamily, rowKey, superColumnName, metadata.getPersistenceUnit(), + consistencyLevel, columnName); + } + + } + } + } + } + } + } + + /** + * @param indexColumnFamily + * @param rowKey + * @param superColumnName + * @param columnName + * TODO + */ + protected abstract void deleteColumn(String indexColumnFamily, String rowKey, byte[] superColumnName, + String persistenceUnit, ConsistencyLevel consistencyLevel, byte[] columnName); + + /** + * @param consistencyLevel + * @param columnFamilyName + * @param rowKey + * @param superColumnName + * @return + */ + protected abstract SuperColumn getSuperColumnForRow(ConsistencyLevel consistencyLevel, String columnFamilyName, + String rowKey, byte[] superColumnName, String persistenceUnit); + + protected abstract void searchSuperColumnsInRange(String columnFamilyName, ConsistencyLevel consistencyLevel, + String persistenceUnit, String rowKey, byte[] searchSuperColumnName, List thriftSuperColumns, + byte[] start, byte[] finish); + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClient.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClient.java new file mode 100644 index 000000000..136f0c3ab --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClient.java @@ -0,0 +1,873 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.cassandra.pelops; + +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.CounterColumn; +import org.apache.cassandra.thrift.CounterSuperColumn; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KeyRange; +import org.apache.cassandra.thrift.KeySlice; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SuperColumn; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.scale7.cassandra.pelops.Bytes; +import org.scale7.cassandra.pelops.Mutator; +import org.scale7.cassandra.pelops.RowDeletor; +import org.scale7.cassandra.pelops.Selector; +import org.scale7.cassandra.pelops.exceptions.PelopsException; +import org.scale7.cassandra.pelops.pool.IThriftPool; +import org.scale7.cassandra.pelops.pool.IThriftPool.IPooledConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.index.InvertedIndexHandler; +import com.impetus.client.cassandra.query.CassQuery; +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.generator.TableGenerator; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.property.PropertyAccessor; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Client implementation using Pelops. http://code.google.com/p/pelops/ + * + * @author animesh.kumar + * @since 0.1 + */ +public class PelopsClient extends CassandraClientBase implements Client, Batcher, TableGenerator +{ + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(PelopsClient.class); + + /** The data handler. */ + private PelopsDataHandler dataHandler; + + /** Handler for Inverted indexing */ + private InvertedIndexHandler invertedIndexHandler; + + /** The reader. */ + private EntityReader reader; + + private PelopsClientFactory clientFactory; + + private IThriftPool pool; + + /** + * default constructor. + * + * @param indexManager + * the index manager + * @param reader + * the reader + * @param persistenceUnit + * the persistence unit + */ + public PelopsClient(IndexManager indexManager, EntityReader reader, PelopsClientFactory clientFactory, + String persistenceUnit, Map externalProperties, IThriftPool pool) + { + super(persistenceUnit, externalProperties); + this.persistenceUnit = persistenceUnit; + this.indexManager = indexManager; + this.dataHandler = new PelopsDataHandler(this); + this.reader = reader; + this.clientFactory = clientFactory; + this.clientMetadata = clientFactory.getClientMetadata(); + this.invertedIndexHandler = new PelopsInvertedIndexHandler(this, MetadataUtils.useSecondryIndex(this.clientMetadata)); + this.pool = pool; + } + + @Override + public final Object find(Class entityClass, Object rowId) + { + return super.find(entityClass, rowId); + } + + @Override + public final List findAll(Class entityClass, String[] columnsToSelect, Object... rowIds) + { + return super.findAll(entityClass, columnsToSelect, rowIds); + } + + /** + * Method to return list of entities for given below attributes:. + * + * @param entityClass + * entity class + * @param relationNames + * relation names + * @param isWrapReq + * true, in case it needs to populate enhance entity. + * @param metadata + * entity metadata. + * @param rowIds + * array of row key s + * @return list of wrapped entities. + */ + @Override + public final List find(Class entityClass, List relationNames, boolean isWrapReq, EntityMetadata metadata, + Object... rowIds) + { + if (!isOpen()) + { + throw new PersistenceException("PelopsClient is closed."); + } + + List entities = null; + Object conn = getConection(); + try + { + entities = dataHandler.fromThriftRow(entityClass, metadata, relationNames, isWrapReq, + getConsistencyLevel(), rowIds); + } + catch (Exception e) + { + log.error("Error while retrieving records for entity {}, row keys {}", entityClass, rowIds); + throw new KunderaException(e); + } + finally + { + releaseConnection(conn); + } + + return entities; + } + + @Override + public void delete(Object entity, Object pKey) + { + if (!isOpen()) + { + throw new PersistenceException("PelopsClient is closed."); + } + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + if (isCql3Enabled(metadata)) + { + String deleteQuery = onDeleteQuery(metadata, metaModel, pKey); + executeQuery(deleteQuery, metadata.getEntityClazz(), null); + } + else + { + + if (metadata.isCounterColumnType()) + { + deleteRecordFromCounterColumnFamily(pKey, metadata, getConsistencyLevel()); + } + else + { + RowDeletor rowDeletor = clientFactory.getRowDeletor(pool); + rowDeletor.deleteRow(metadata.getTableName(), + CassandraUtilities.toBytes(pKey, metadata.getIdAttribute().getJavaType()), + getConsistencyLevel()); + + } + } + // Delete from Lucene if applicable + getIndexManager().remove(metadata, entity, pKey.toString()); + + // Delete from Inverted Index if applicable + Object conn = getConection(); + try + { + invertedIndexHandler.delete(entity, metadata, getConsistencyLevel()); + } + finally + { + if (conn != null) + { + releaseConnection(conn); + } + } + } + + @Override + public final void close() + { + this.indexManager.flush(); + this.dataHandler = null; + this.invertedIndexHandler = null; + } + + /** + * Persists records into Join Table + */ + public void persistJoinTable(JoinTableData joinTableData) + { + Mutator mutator = clientFactory.getMutator(pool); + + String joinTableName = joinTableData.getJoinTableName(); + String invJoinColumnName = joinTableData.getInverseJoinColumnName(); + Map> joinTableRecords = joinTableData.getJoinTableRecords(); + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(joinTableData.getEntityClass()); + + for (Object key : joinTableRecords.keySet()) + { + Set values = joinTableRecords.get(key); + + List columns = new ArrayList(); + + Class columnType = null; + for (Object value : values) + { + Column column = new Column(); + column.setName(PropertyAccessorFactory.STRING.toBytes(invJoinColumnName + + Constants.JOIN_COLUMN_NAME_SEPARATOR + value.toString())); + // column.setValue(PropertyAccessorFactory.STRING.toBytes((String) + // value)); + column.setValue(PropertyAccessorHelper.getBytes(value)); + column.setTimestamp(System.currentTimeMillis()); + columnType = value.getClass(); + columns.add(column); + } + + createIndexesOnColumns(entityMetadata, joinTableName, columns, columnType); + // Object pk = key; + + mutator.writeColumns(joinTableName, Bytes.fromByteArray(PropertyAccessorHelper.getBytes(key)), + Arrays.asList(columns.toArray(new Column[0]))); + } + + if (log.isInfoEnabled()) + { + log.info(" Persisted data with join table column family {}", joinTableData.getJoinTableName()); + } + mutator.execute(getConsistencyLevel()); + } + + @Override + public List getColumnsById(String schemaName, String joinTableName, String joinColumnName, + String inverseJoinColumnName, Object parentId, Class columnJavaType) + { + Selector selector = clientFactory.getSelector(pool); + + List columns = selector.getColumnsFromRow(joinTableName, + Bytes.fromByteArray(PropertyAccessorHelper.getBytes(parentId)), + Selector.newColumnsPredicateAll(true, 10), getConsistencyLevel()); + + List foreignKeys = dataHandler.getForeignKeysFromJoinTable(inverseJoinColumnName, columns, + columnJavaType); + + if (log.isInfoEnabled()) + { + log.info("Returning number of keys from join table", foreignKeys != null ? foreignKeys.size() : null); + } + + return (List) foreignKeys; + } + + @Override + public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName, + Object columnValue, Class entityClazz) + { + Selector selector = clientFactory.getSelector(pool); + SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, 10000); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entityClazz); + // String childIdStr = (String) columnValue; + + IndexClause ix = Selector.newIndexClause(Bytes.EMPTY, 10000, Selector.newIndexExpression(columnName + + Constants.JOIN_COLUMN_NAME_SEPARATOR + columnValue, IndexOperator.EQ, + Bytes.fromByteArray(PropertyAccessorHelper.getBytes(columnValue)))); + + Map> qResults = selector.getIndexedColumns(tableName, ix, slicePredicate, + getConsistencyLevel()); + + List rowKeys = new ArrayList(); + + // iterate through complete map and + Iterator rowIter = qResults.keySet().iterator(); + while (rowIter.hasNext()) + { + Bytes rowKey = rowIter.next(); + + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor((Field) metadata + .getIdAttribute().getJavaMember()); + Object value = accessor.fromBytes(metadata.getIdAttribute().getJavaType(), rowKey.toByteArray()); + + rowKeys.add(value); + } + + if (rowKeys != null && !rowKeys.isEmpty()) + { + return rowKeys.toArray(new Object[0]); + } + + if (log.isInfoEnabled()) + { + log.info("No row keys found, returning null."); + } + return null; + } + + @Override + public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) + { + + if (!isOpen()) + { + throw new PersistenceException("PelopsClient is closed."); + } + + RowDeletor rowDeletor = clientFactory.getRowDeletor(pool); + // rowDeletor.deleteRow(tableName, columnValue.toString(), + // getConsistencyLevel()); + rowDeletor.deleteRow(tableName, CassandraUtilities.toBytes(columnValue, columnValue.getClass()), + getConsistencyLevel()); + + } + + @Override + public List find(Class entityClass, Map embeddedColumnMap) + { + return super.find(entityClass, embeddedColumnMap, dataHandler); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#find(java.lang.String, + * java.lang.String, com.impetus.kundera.metadata.model.EntityMetadata) + */ + @Override + public List findByRelation(String colName, Object colValue, Class clazz) + { + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(clazz); + List entities = null; + if (isCql3Enabled(m)) + { + entities = findByRelationQuery(m, colName, colValue, clazz, dataHandler); + } + else + { + Selector selector = clientFactory.getSelector(pool); + SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, 10000); + IndexClause ix = Selector.newIndexClause( + Bytes.EMPTY, + 10000, + Selector.newIndexExpression(colName, IndexOperator.EQ, + Bytes.fromByteArray(PropertyAccessorHelper.getBytes(colValue)))); + Map> qResults; + try + { + qResults = selector.getIndexedColumns(m.getTableName(), ix, slicePredicate, getConsistencyLevel()); + } + catch (PelopsException e) + { + log.warn("Error while retrieving entities for given column {} for class {}.", colName, clazz); + return entities; + } + entities = new ArrayList(qResults.size()); + // iterate through complete map and + populateData(m, qResults, entities, false, m.getRelationNames(), dataHandler); + } + return entities; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#getReader() + */ + @Override + public EntityReader getReader() + { + return reader; + } + + @Override + public Class getQueryImplementor() + { + return CassQuery.class; + } + + @Override + protected void onPersist(EntityMetadata metadata, Object entity, Object id, List rlHolders) + { + + if (!isOpen()) + { + throw new PersistenceException("PelopsClient is closed."); + } + + // check for counter column + if (isUpdate && metadata.isCounterColumnType()) + { + throw new UnsupportedOperationException("Merge is not permitted on counter column! "); + } + + String insert_Query = null; + if (isCql3Enabled(metadata)) + { + Cassandra.Client client = getRawClient(metadata.getPersistenceUnit(), metadata.getSchema()); + try + { + client.set_keyspace(metadata.getSchema()); + insert_Query = createInsertQuery(metadata, entity, client, rlHolders, getTtlValues().get(metadata.getTableName())); + executeCQLQuery(insert_Query,true); + } + catch (InvalidRequestException e) + { + log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e); + throw new KunderaException(e); + } + catch (SchemaDisagreementException e) + { + log.error("Error during persist while executing query {}, Caused by: .", insert_Query, e); + throw new KunderaException(e); + } + } + else + { + ThriftRow tf = null; + try + { + String columnFamily = metadata.getTableName(); + tf = dataHandler.toThriftRow(entity, id, metadata, columnFamily, getTtlValues().get(columnFamily)); + } + catch (Exception e) + { + log.error("Error during persist, Caused by: .", e); + throw new KunderaException(e); + } + addRelationsToThriftRow(metadata, tf, rlHolders); + Mutator mutator = clientFactory.getMutator(pool); + if (metadata.isCounterColumnType()) + { + if (log.isInfoEnabled()) + { + log.info("Persisting counter column family record for row key {}", tf.getId()); + } + List thriftCounterColumns = tf.getCounterColumns(); + List thriftCounterSuperColumns = tf.getCounterSuperColumns(); + if (thriftCounterColumns != null && !thriftCounterColumns.isEmpty()) + { + mutator.writeCounterColumns(metadata.getTableName(), + CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass()), + Arrays.asList(tf.getCounterColumns().toArray(new CounterColumn[0]))); + } + + if (thriftCounterSuperColumns != null && !thriftCounterSuperColumns.isEmpty()) + { + for (CounterSuperColumn sc : thriftCounterSuperColumns) + { + mutator.writeSubCounterColumns(metadata.getTableName(), + CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass()), + Bytes.fromByteArray(sc.getName()), sc.getColumns()); + } + } + } + else + { + List thriftColumns = tf.getColumns(); + List thriftSuperColumns = tf.getSuperColumns(); + if (thriftColumns != null && !thriftColumns.isEmpty()) + { + if (log.isInfoEnabled()) + { + log.info("Persisting column family record for row key {}", tf.getId()); + } + + // Bytes.from + mutator.writeColumns(metadata.getTableName(), + CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass()), + Arrays.asList(tf.getColumns().toArray(new Column[0]))); + } + + if (thriftSuperColumns != null && !thriftSuperColumns.isEmpty()) + { + for (SuperColumn sc : thriftSuperColumns) + { + if (log.isInfoEnabled()) + { + log.info("Persisting super column family record for row key {}", tf.getId()); + } + + mutator.writeSubColumns(metadata.getTableName(), + CassandraUtilities.toBytes(tf.getId(), tf.getId().getClass()), + Bytes.fromByteArray(sc.getName()), sc.getColumns()); + } + } + } + + mutator.execute(getConsistencyLevel()); + tf = null; + + if(isTtlPerRequest()) + { + getTtlValues().clear(); + } + } + } + + /** + * Indexes @Embedded and @ElementCollection objects of this entity to a + * separate column family + */ + @Override + protected void indexNode(Node node, EntityMetadata entityMetadata) + { + // Index to lucene if applicable + super.indexNode(node, entityMetadata); + + // Write to inverted index table if applicable + // Delete from Inverted Index if applicable + invertedIndexHandler.write(node, entityMetadata, getPersistenceUnit(), getConsistencyLevel(), dataHandler); + } + + /** + * Load super columns. + * + * @param keyspace + * the keyspace + * @param columnFamily + * the column family + * @param rowId + * the row id + * @param superColumnNames + * the super column names + * @return the list + */ + + @Override + public final List loadSuperColumns(String keyspace, String columnFamily, String rowId, + String... superColumnNames) + { + if (!isOpen()) + throw new PersistenceException("PelopsClient is closed."); + Selector selector = clientFactory.getSelector(pool); + List rowKeys = new ArrayList(); + rowKeys.add(ByteBuffer.wrap(rowId.getBytes())); + + // Pelops.getDbConnPool("").getConnection().getAPI(). + + // selector.getColumnOrSuperColumnsFromRows(new + // ColumnParent(columnFamily),rowKeys , + // Selector.newColumnsPredicate(superColumnNames), + // getConsistencyLevel()); + + if (log.isInfoEnabled()) + { + log.info("Retrieving record of super column family {} for row key {}", columnFamily, rowId); + } + + return selector.getSuperColumnsFromRow(columnFamily, rowId, Selector.newColumnsPredicate(superColumnNames), + getConsistencyLevel()); + } + + /** Query related methods */ + + /** + * Method to execute cql query and return back entity/enhance entities. + * + * @param cqlQuery + * cql query to be executed. + * @param clazz + * entity class. + * @param relationalField + * collection for relational fields. + * @return list of objects. + * + */ + @Override + public List executeQuery(String cqlQuery, Class clazz, List relationalField) + { + return super.executeQuery(cqlQuery, clazz, relationalField, dataHandler); + } + + /** + * Find. + * + * @param ixClause + * the ix clause + * @param m + * the m + * @param isRelation + * the is relation + * @param relations + * the relations + * @return the list + */ + @Override + public List find(List ixClause, EntityMetadata m, boolean isRelation, List relations, + int maxResult, List columns) + { + Selector selector = clientFactory.getSelector(pool); + + SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, Integer.MAX_VALUE); + if (columns != null && !columns.isEmpty()) + { + slicePredicate = Selector.newColumnsPredicate(columns.toArray(new String[] {})); + } + + List entities = new ArrayList(); + if (ixClause.isEmpty()) + { + if (m.isCounterColumnType()) + { + + try + { + IPooledConnection connection = getConection(); + org.apache.cassandra.thrift.Cassandra.Client thriftClient = connection.getAPI(); + List ks = thriftClient.get_range_slices(new ColumnParent(m.getTableName()), + slicePredicate, Selector.newKeyRange("", "", maxResult), getConsistencyLevel()); + connection.release(); + entities = onCounterColumn(m, isRelation, relations, ks); + } + catch (InvalidRequestException irex) + { + log.error("Error during executing find, Caused by: .", irex); + throw new PersistenceException(irex); + } + catch (UnavailableException uex) + { + log.error("Error during executing find, Caused by: .", uex); + throw new PersistenceException(uex); + } + catch (TimedOutException tex) + { + log.error("Error during executing find, Caused by: .", tex); + throw new PersistenceException(tex); + } + catch (TException tex) + { + log.error("Error during executing find, Caused by: .", tex); + throw new PersistenceException(tex); + } + } + else + { + + if (m.getType().isSuperColumnFamilyMetadata()) + { + Map> qResults = selector.getSuperColumnsFromRows(m.getTableName(), + selector.newKeyRange("", "", maxResult), slicePredicate, getConsistencyLevel()); + entities = new ArrayList(qResults.size()); + computeEntityViaSuperColumns(m, isRelation, relations, entities, qResults); + } + else + { + Map> qResults = selector.getColumnsFromRows(m.getTableName(), + selector.newKeyRange("", "", maxResult), slicePredicate, getConsistencyLevel()); + entities = new ArrayList(qResults.size()); + // populateData(m, qResults, entities, isRelation, + // relations, dataHandler); + computeEntityViaColumns(m, isRelation, relations, entities, qResults); + } + + } + } + else + { + entities = new ArrayList(); + for (IndexClause ix : ixClause) + { + Map> qResults = selector.getIndexedColumns(m.getTableName(), ix, slicePredicate, + getConsistencyLevel()); + computeEntityViaColumns(m, isRelation, relations, entities, qResults); + // // iterate through complete map and + // populateData(m, qResults, entities, isRelation, relations, + // dataHandler); + } + } + return entities; + } + + /** + * Find. + * + * @param m + * the m + * @param relationNames + * the relation names + * @param conditions + * the conditions + * @return the list + */ + public List find(EntityMetadata m, List relationNames, List conditions, + int maxResult, List columns) + { + return (List) find(conditions, m, true, relationNames, maxResult, columns); + } + + /** + * Find by range. + * + * @param minVal + * the min val + * @param maxVal + * the max val + * @param m + * the m + * @param isWrapReq + * the is wrap req + * @param relations + * the relations + * @return the list + * @throws Exception + * the exception + */ + @Override + public List findByRange(byte[] minVal, byte[] maxVal, EntityMetadata m, boolean isWrapReq, List relations, + List columns, List conditions,int maxResults) throws Exception + { + Selector selector = clientFactory.getSelector(pool); + + SlicePredicate slicePredicate = Selector.newColumnsPredicateAll(false, Integer.MAX_VALUE); + if (columns != null && !columns.isEmpty()) + { + slicePredicate = Selector.newColumnsPredicate(columns.toArray(new String[] {})); + } + + KeyRange keyRange = selector.newKeyRange(minVal != null ? Bytes.fromByteArray(minVal) : Bytes.fromUTF8(""), + maxVal != null ? Bytes.fromByteArray(maxVal) : Bytes.fromUTF8(""), maxResults); + if (conditions != null) + { + keyRange.setRow_filter(conditions); + keyRange.setRow_filterIsSet(true); + } + // List entities = null; + List keys = selector.getKeySlices(new ColumnParent(m.getTableName()), keyRange, slicePredicate, + getConsistencyLevel()); + + List results = null; + if (keys != null) + { + results = populateEntitiesFromKeySlices(m, isWrapReq, relations, keys, dataHandler); + } + + if (log.isInfoEnabled()) + { + log.info("Returning entities for find by range for", results != null ? results.size() : null); + } + + return results; + } + + public List searchInInvertedIndex(String columnFamilyName, EntityMetadata m, + Map> indexClauseMap) + { + // Delete from Inverted Index if applicable + Object conn = getConection(); + try + { + return invertedIndexHandler.search(m, getPersistenceUnit(), getConsistencyLevel(), indexClauseMap); + } + finally + { + releaseConnection(conn); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.cassandra.CassandraClientBase#getDataHandler() + */ + @Override + protected CassandraDataHandler getDataHandler() + { + return dataHandler; + } + + protected IPooledConnection getConection() + { + return clientFactory.getConnection(pool); + } + + protected void releaseConnection(Object conn) + { + clientFactory.releaseConnection((IPooledConnection) conn); + } + + @Override + public Long generate(TableGeneratorDiscriptor discriptor) + { + return getGeneratedValue(discriptor, getPersistenceUnit()); + } + + Mutator getMutator() + { + return clientFactory.getMutator(pool); + } + + Selector getSelector() + { + return clientFactory.getSelector(pool); + } + + RowDeletor getRowDeletor() + { + return clientFactory.getRowDeletor(pool); + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClientFactory.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClientFactory.java new file mode 100644 index 000000000..ed5e54a20 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsClientFactory.java @@ -0,0 +1,484 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.pelops; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.scale7.cassandra.pelops.Cluster; +import org.scale7.cassandra.pelops.Cluster.Node; +import org.scale7.cassandra.pelops.IConnection; +import org.scale7.cassandra.pelops.Mutator; +import org.scale7.cassandra.pelops.Pelops; +import org.scale7.cassandra.pelops.RowDeletor; +import org.scale7.cassandra.pelops.Selector; +import org.scale7.cassandra.pelops.exceptions.TransportException; +import org.scale7.cassandra.pelops.pool.CommonsBackedPool; +import org.scale7.cassandra.pelops.pool.CommonsBackedPool.Policy; +import org.scale7.cassandra.pelops.pool.IThriftPool; +import org.scale7.cassandra.pelops.pool.IThriftPool.IPooledConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.query.CassandraEntityReader; +import com.impetus.client.cassandra.schemamanager.CassandraSchemaManager; +import com.impetus.client.cassandra.service.CassandraHost; +import com.impetus.client.cassandra.service.CassandraHostConfiguration; +import com.impetus.client.cassandra.service.CassandraRetryService; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.GenericClientFactory; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.service.Host; +import com.impetus.kundera.service.HostConfiguration; +import com.impetus.kundera.service.policy.LeastActiveBalancingPolicy; +import com.impetus.kundera.service.policy.RoundRobinBalancingPolicy; + +/** + * A factory for creating PelopsCliobjects. + */ +public class PelopsClientFactory extends GenericClientFactory +{ + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(PelopsClientFactory.class); + + private HostConfiguration configuration; + + @Override + public void initialize(Map externalProperty) + { + reader = new CassandraEntityReader(); + initializePropertyReader(); +// setExternalProperties(externalProperty); + String loadBalancingPolicyName = CassandraPropertyReader.csmd != null ? CassandraPropertyReader.csmd + .getConnectionProperties().getProperty(Constants.LOADBALANCING_POLICY) : null; + initializeLoadBalancer(loadBalancingPolicyName); + configuration = new CassandraHostConfiguration(externalProperties, CassandraPropertyReader.csmd, + getPersistenceUnit()); + hostRetryService = new CassandraRetryService(configuration, this); + } + + @Override + protected Object createPoolOrConnection() + { + logger.info("Creating pool"); + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + + Properties props = persistenceUnitMetadata.getProperties(); + String keyspace = null; + if (externalProperties != null) + { + keyspace = (String) externalProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + if (keyspace == null) + { + keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + + for (Host host : ((CassandraHostConfiguration) configuration).getCassandraHosts()) + { + CassandraHost cassandraHost = (CassandraHost) host; + String poolName = PelopsUtils.generatePoolName(cassandraHost.getHost(), cassandraHost.getPort(), keyspace); + if (PelopsUtils.verifyConnection(cassandraHost.getHost(), cassandraHost.getPort())) + { + Cluster cluster = new Cluster(cassandraHost.getHost(), new IConnection.Config(cassandraHost.getPort(), + true, -1, PelopsUtils.getAuthenticationRequest(cassandraHost.getUser(), + cassandraHost.getPassword())), false); + + if (logger.isInfoEnabled()) + { + logger.info("Initializing connection pool for keyspace {}, host {},port {}.", keyspace, + cassandraHost.getHost(), cassandraHost.getPort()); + } + + Policy policy = PelopsUtils.getPoolConfigPolicy(cassandraHost); + + // Add pool with specified policy. null means default operand + // policy. + Pelops.addPool(poolName, cluster, keyspace, policy, null); + hostPools.put(cassandraHost, Pelops.getDbConnPool(poolName)); + } + else + { + logger.warn("Node " + host.getHost() + " are down"); + if (host.isRetryHost()) + { + logger.info("Scheduling node for future retry"); + ((CassandraRetryService) hostRetryService).add((CassandraHost) host); + } + } + } + // TODO return a thrift pool + return null; + } + + @Override + protected Client instantiateClient(String persistenceUnit) + { + if (logger.isInfoEnabled()) + { + logger.info("Initializing pelops client for persistence unit {}", persistenceUnit); + } + IThriftPool pool = getPoolUsingPolicy(); + return new PelopsClient(indexManager, reader, this, persistenceUnit, externalProperties, pool); + } + + @Override + public boolean isThreadSafe() + { + return false; + } + + @Override + public void destroy() + { + if (indexManager != null) + { + indexManager.close(); + } + if (schemaManager != null) + { + schemaManager.dropSchema(); + } + schemaManager = null; + // Pelops.shutdown(); + // Pelops.removePool(PelopsUtils.generatePoolName(getPersistenceUnit(), + // externalProperties)); + externalProperties = null; + } + + @Override + public SchemaManager getSchemaManager(Map externalProperty) + { + if (schemaManager == null) + { + initializePropertyReader(); + setExternalProperties(externalProperty); + schemaManager = new CassandraSchemaManager(PelopsClientFactory.class.getName(), externalProperty); + } + + return schemaManager; + } + + /** + * + */ + private void initializePropertyReader() + { + if (propertyReader == null) + { + propertyReader = new CassandraPropertyReader(externalProperties); + propertyReader.read(getPersistenceUnit()); + } + } + + @Override + protected void initializeLoadBalancer(String loadBalancingPolicyName) + { + switch (LoadBalancer.getValue(loadBalancingPolicyName)) + { + case ROUNDROBIN: + loadBalancingPolicy = new RoundRobinBalancingPolicy(); + break; + case LEASTACTIVE: + loadBalancingPolicy = new PelopsLeastActiveBalancingPolcy(); + break; + default: + loadBalancingPolicy = new RoundRobinBalancingPolicy(); + break; + } + } + + /** + * + * @return pool an the basis of LoadBalancing policy. + */ + private IThriftPool getPoolUsingPolicy() + { + if (!hostPools.isEmpty()) + { + logger.info("Retruning pool using {} .", loadBalancingPolicy.getClass().getSimpleName()); + return (IThriftPool) loadBalancingPolicy.getPool(hostPools.values()); + } + throw new KunderaException("All hosts are down. please check servers manully."); + } + + IPooledConnection getConnection(IThriftPool pool) + { + IThriftPool iThriftPool = pool; + boolean success = false; + while (!success) + { + success = true; + if (iThriftPool != null) + { + Node[] nodes = ((CommonsBackedPool) iThriftPool).getCluster().getNodes(); + String host = nodes[0].getAddress(); + int thriftPort = ((CommonsBackedPool) iThriftPool).getCluster().getConnectionConfig().getThriftPort(); + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost( + nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster().getConnectionConfig() + .getThriftPort()); + if (cassandraHost.isTestOnBorrow()) + { + if (cassandraHost.isTestOnBorrow() && PelopsUtils.verifyConnection(host, thriftPort)) + { + logger.info("Retruning connection of {} :{} .", nodes[0].getAddress(), thriftPort); + return iThriftPool.getConnection(); + } + removePool(iThriftPool); + } + else + { + logger.info("Retruning connection of {} :{} .", nodes[0].getAddress(), thriftPort); + return iThriftPool.getConnection(); + } + removePool(iThriftPool); + } + success = false; + iThriftPool = getPoolUsingPolicy(); + } + throw new KunderaException("All hosts are down. please check servers manully."); + } + + Mutator getMutator(IThriftPool pool) + { + IThriftPool iThriftPool = pool; + boolean success = false; + while (!success) + { + success = true; + if (iThriftPool != null) + { + Node[] nodes = ((CommonsBackedPool) iThriftPool).getCluster().getNodes(); + String host = nodes[0].getAddress(); + int thriftPort = ((CommonsBackedPool) iThriftPool).getCluster().getConnectionConfig().getThriftPort(); + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost( + nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster().getConnectionConfig() + .getThriftPort()); + if (cassandraHost.isTestOnBorrow()) + { + if (cassandraHost.isTestOnBorrow() && PelopsUtils.verifyConnection(host, thriftPort)) + { + logger.info("Retruning mutator of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createMutator(PelopsUtils.getPoolName(iThriftPool)); + } + removePool(iThriftPool); + } + else + { + logger.info("Retruning mutator of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createMutator(PelopsUtils.getPoolName(iThriftPool)); + } + } + success = false; + iThriftPool = getPoolUsingPolicy(); + } + throw new KunderaException("All hosts are down. please check servers manully."); + } + + Selector getSelector(IThriftPool pool) + { + IThriftPool iThriftPool = pool; + boolean success = false; + while (!success) + { + if (iThriftPool != null) + { + Node[] nodes = ((CommonsBackedPool) iThriftPool).getCluster().getNodes(); + String host = nodes[0].getAddress(); + int thriftPort = ((CommonsBackedPool) iThriftPool).getCluster().getConnectionConfig().getThriftPort(); + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost( + nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster().getConnectionConfig() + .getThriftPort()); + if (cassandraHost.isTestOnBorrow()) + { + if (cassandraHost.isTestOnBorrow() && PelopsUtils.verifyConnection(host, thriftPort)) + { + logger.info("Retruning selector of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createSelector(PelopsUtils.getPoolName(iThriftPool)); + } + removePool(iThriftPool); + } + else + { + logger.info("Retruning selector of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createSelector(PelopsUtils.getPoolName(iThriftPool)); + } + } + success = false; + iThriftPool = getPoolUsingPolicy(); + } + throw new KunderaException("All hosts are down. please check servers manully."); + } + + RowDeletor getRowDeletor(IThriftPool pool) + { + IThriftPool iThriftPool = pool; + boolean success = false; + while (!success) + { + if (iThriftPool != null) + { + Node[] nodes = ((CommonsBackedPool) iThriftPool).getCluster().getNodes(); + String host = nodes[0].getAddress(); + int thriftPort = ((CommonsBackedPool) iThriftPool).getCluster().getConnectionConfig().getThriftPort(); + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost( + nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster().getConnectionConfig() + .getThriftPort()); + if (cassandraHost.isTestOnBorrow()) + { + if (cassandraHost.isTestOnBorrow() && PelopsUtils.verifyConnection(host, thriftPort)) + { + logger.info("Retruning row deletor of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createRowDeletor(PelopsUtils.getPoolName(iThriftPool)); + } + removePool(iThriftPool); + } + else + { + logger.info("Retruning row deletor of {} :{} .", nodes[0].getAddress(), thriftPort); + return Pelops.createRowDeletor(PelopsUtils.getPoolName(iThriftPool)); + } + } + success = false; + iThriftPool = getPoolUsingPolicy(); + } + throw new KunderaException("All hosts are down. please check servers manully."); + + } + + void releaseConnection(IPooledConnection conn) + { + if (conn != null) + { + conn.release(); + } + } + + /** + * Adds a pool in hostPools map for given host. + * + * @param cassandraHost + * @return true id added successfully. + */ + public boolean addCassandraHost(CassandraHost cassandraHost) + { + Properties props = KunderaMetadataManager.getPersistenceUnitMetadata(getPersistenceUnit()).getProperties(); + String keyspace = null; + if (externalProperties != null) + { + keyspace = (String) externalProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + if (keyspace == null) + { + keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + String poolName = PelopsUtils.generatePoolName(cassandraHost.getHost(), cassandraHost.getPort(), keyspace); + Cluster cluster = new Cluster(cassandraHost.getHost(), new IConnection.Config(cassandraHost.getPort(), true, + -1, PelopsUtils.getAuthenticationRequest(cassandraHost.getUser(), cassandraHost.getPassword())), false); + Policy policy = PelopsUtils.getPoolConfigPolicy(cassandraHost); + try + { + Pelops.addPool(poolName, cluster, keyspace, policy, null); + hostPools.put(cassandraHost, Pelops.getDbConnPool(poolName)); + return true; + } + catch (TransportException e) + { + logger.warn("Node {} are still down ", cassandraHost.getHost()); + return false; + } + } + + /** + * Removes downed host pool from pool map. + * + * @param pool + */ + private void removePool(IThriftPool pool) + { + Pelops.removePool(PelopsUtils.getPoolName(pool)); + Node[] nodes = ((CommonsBackedPool) pool).getCluster().getNodes(); + logger.warn("{} :{} host appears to be down, trying for next ", nodes, ((CommonsBackedPool) pool).getCluster() + .getConnectionConfig().getThriftPort()); + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost( + nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster().getConnectionConfig().getThriftPort()); + hostPools.remove(cassandraHost); + } + + /** + * Extends LeastActiveBalancingPolicy class and provide own implementation + * in order to support least active balancing policy. + * + * @author Kuldeep.Mishra + * + */ + private class PelopsLeastActiveBalancingPolcy extends LeastActiveBalancingPolicy + { + + /** + * + * @return pool object for host which has least active connections + * determined by maxActive connection. + * + */ + public Object getPool(Collection pools) + { + List vals = Lists.newArrayList(pools); + Collections.shuffle(vals); + Collections.sort(vals, new ShufflingCompare()); + Collections.reverse(vals); + Iterator iterator = vals.iterator(); + Object concurrentConnectionPool = iterator.next(); + return concurrentConnectionPool; + } + + /** + * Compares two pool object on the basis of their maxActive connection + * per node. + * + * @author Kuldeep Mishra + * + */ + private final class ShufflingCompare implements Comparator + { + public int compare(Object o1, Object o2) + { + Policy policy1 = ((CommonsBackedPool) ((IThriftPool) o1)).getPolicy(); + Policy policy2 = ((CommonsBackedPool) ((IThriftPool) o2)).getPolicy(); + + int activeConnections1 = ((CommonsBackedPool) ((IThriftPool) o1)).getConnectionsActive(); + int activeConnections2 = ((CommonsBackedPool) ((IThriftPool) o2)).getConnectionsActive(); + + return (policy1.getMaxActivePerNode() - activeConnections1) + - (policy2.getMaxActivePerNode() - activeConnections2); + } + } + } +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsDataHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsDataHandler.java new file mode 100644 index 000000000..158d41409 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsDataHandler.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.pelops; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.SuperColumn; +import org.scale7.cassandra.pelops.Selector; + +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.datahandler.CassandraDataHandlerBase; +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.db.DataRow; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Provides Pelops utility methods for data held in Column family based stores. + * + * @author amresh.singh + */ +final class PelopsDataHandler extends CassandraDataHandlerBase implements CassandraDataHandler +{ + + private final PelopsClient pelopsClient; + + /** + * @param externalProperties + */ + public PelopsDataHandler(final PelopsClient pelopsClient) + { + super(pelopsClient); + this.pelopsClient = pelopsClient; + } + + @Override + public Object fromThriftRow(Class clazz, EntityMetadata m, Object rowKey, List relationNames, + boolean isWrapReq, ConsistencyLevel consistencyLevel) throws Exception + { + Selector selector = pelopsClient.getSelector(); + + List rowKeys = new ArrayList(1); + rowKeys.add(ByteBuffer.wrap(PropertyAccessorHelper.toBytes(rowKey, m.getIdAttribute().getJavaType()))); + + Map> thriftColumnOrSuperColumns = selector + .getColumnOrSuperColumnsFromRows(new ColumnParent(m.getTableName()), rowKeys, + Selector.newColumnsPredicateAll(true, 10000), consistencyLevel); + + ThriftRow tr = new ThriftRow(); + tr.setId(rowKey); + tr.setColumnFamilyName(m.getTableName()); + + tr = thriftTranslator + .translateToThriftRow(thriftColumnOrSuperColumns, m.isCounterColumnType(), m.getType(), tr); + + return populateEntity(tr, m, relationNames, isWrapReq); + } + + /** Translation Methods */ + + @Override + public List fromThriftRow(Class clazz, EntityMetadata m, List relationNames, boolean isWrapReq, + ConsistencyLevel consistencyLevel, Object... rowIds) throws Exception + { + return super.fromThriftRow(clazz, m, relationNames, isWrapReq, consistencyLevel, rowIds); + } + + @Override + public E fromThriftRow(Class clazz, EntityMetadata m, DataRow tr) throws Exception + { + return super.fromThriftRow(clazz, m, tr); + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsInvertedIndexHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsInvertedIndexHandler.java new file mode 100644 index 000000000..a4e1c1fb5 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsInvertedIndexHandler.java @@ -0,0 +1,215 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.pelops; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.SuperColumn; +import org.scale7.cassandra.pelops.Bytes; +import org.scale7.cassandra.pelops.Mutator; +import org.scale7.cassandra.pelops.Selector; +import org.scale7.cassandra.pelops.exceptions.NotFoundException; +import org.scale7.cassandra.pelops.exceptions.PelopsException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.index.CassandraIndexHelper; +import com.impetus.client.cassandra.index.InvertedIndexHandler; +import com.impetus.client.cassandra.index.InvertedIndexHandlerBase; +import com.impetus.client.cassandra.thrift.ThriftRow; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Pelops implementation of {@link InvertedIndexHandler} + * + * @author amresh.singh + */ +public class PelopsInvertedIndexHandler extends InvertedIndexHandlerBase implements InvertedIndexHandler +{ + private static final Logger log = LoggerFactory.getLogger(PelopsInvertedIndexHandler.class); + + private final PelopsClient pelopsClient; + + /** + * @param externalProperties + */ + public PelopsInvertedIndexHandler(final PelopsClient pelopsClient, final boolean useSecondryIndex) + { + this.pelopsClient = pelopsClient; + this.useSecondryIndex = useSecondryIndex; + } + + @Override + public void write(Node node, EntityMetadata entityMetadata, String persistenceUnit, + ConsistencyLevel consistencyLevel, CassandraDataHandler cdHandler) + { + // Index in Inverted Index table if applicable + boolean invertedIndexingApplicable = CassandraIndexHelper.isInvertedIndexingApplicable(entityMetadata,useSecondryIndex); + + if (invertedIndexingApplicable) + { + String indexColumnFamily = CassandraIndexHelper.getInvertedIndexTableName(entityMetadata.getTableName()); + + Mutator mutator = pelopsClient.getMutator(); + + List indexThriftyRows = ((PelopsDataHandler) cdHandler).toIndexThriftRow(node.getData(), + entityMetadata, indexColumnFamily); + + for (ThriftRow thriftRow : indexThriftyRows) + { + + List thriftColumns = thriftRow.getColumns(); + List thriftSuperColumns = thriftRow.getSuperColumns(); + if (thriftColumns != null && !thriftColumns.isEmpty()) + { + // Bytes.fromL + mutator.writeColumns(thriftRow.getColumnFamilyName(), + CassandraUtilities.toBytes(thriftRow.getId(), thriftRow.getId().getClass()), + Arrays.asList(thriftRow.getColumns().toArray(new Column[0]))); + } + + if (thriftSuperColumns != null && !thriftSuperColumns.isEmpty()) + { + for (SuperColumn sc : thriftSuperColumns) + { + mutator.writeSubColumns(thriftRow.getColumnFamilyName(), + CassandraUtilities.toBytes(thriftRow.getId(), thriftRow.getId().getClass()), + Bytes.fromByteArray(sc.getName()), sc.getColumns()); + } + } + + } + mutator.execute(consistencyLevel); + indexThriftyRows = null; + } + } + + /** + * @param columnFamilyName + * @param m + * @param filterClauseQueue + * @return + */ + @Override + public List search(EntityMetadata m, String persistenceUnit, ConsistencyLevel consistencyLevel, + Map> indexClauseMap) + { + return super.search(m, persistenceUnit, consistencyLevel, indexClauseMap); + } + + /** + * Searches searchString into columnFamilyName + * (usually a wide row column family) for a given rowKey from + * start to finish columns. Adds matching thrift columns into + * thriftColumns + * + * @param columnFamilyName + * @param consistencyLevel + * @param selector + * @param rowKey + * @param searchString + * @param thriftSuperColumns + */ + @Override + public void searchSuperColumnsInRange(String columnFamilyName, ConsistencyLevel consistencyLevel, + String persistenceUnit, String rowKey, byte[] searchSuperColumnName, List thriftSuperColumns, + byte[] start, byte[] finish) + { + SlicePredicate colPredicate = new SlicePredicate(); + SliceRange sliceRange = new SliceRange(); + sliceRange.setStart(start); + sliceRange.setFinish(finish); + colPredicate.setSlice_range(sliceRange); + + Selector selector = pelopsClient.getSelector(); + List allThriftSuperColumns = selector.getSuperColumnsFromRow(columnFamilyName, rowKey, + colPredicate, consistencyLevel); + + for (SuperColumn superColumn : allThriftSuperColumns) + { + if (superColumn == null) + continue; + if (superColumn.getName() == searchSuperColumnName) + { + thriftSuperColumns.add(superColumn); + } + } + } + + /** + * Deletes records from inverted index table + * + * @param entity + * @param metadata + */ + + @Override + public void delete(Object entity, EntityMetadata metadata, ConsistencyLevel consistencyLevel) + { + super.delete(entity, metadata, consistencyLevel); + } + + @Override + public SuperColumn getSuperColumnForRow(ConsistencyLevel consistencyLevel, String columnFamilyName, String rowKey, + byte[] superColumnName, String persistenceUnit) + { + Selector selector = pelopsClient.getSelector(); + SuperColumn thriftSuperColumn = null; + try + { + thriftSuperColumn = selector.getSuperColumnFromRow(columnFamilyName, rowKey, + Bytes.fromByteArray(superColumnName), consistencyLevel); + + } + catch (NotFoundException e) + { + log.error("Error while fetching super column for Row {} , Caused by: .",rowKey, e); + return null; + } + catch (PelopsException e) + { + log.error("Error while fetching super column for Row {} , Caused by: .",rowKey, e); + return null; + } + return thriftSuperColumn; + } + + /** + * @param indexColumnFamily + * @param rowKey + * @param superColumnName + * @param mutator + */ + public void deleteColumn(String indexColumnFamily, String rowKey, byte[] superColumnName, String persistenceUnit, + ConsistencyLevel consistencyLevel, byte[] columnName) + { + Mutator mutator = pelopsClient.getMutator(); + mutator.deleteColumn(indexColumnFamily, rowKey, Bytes.fromByteArray(superColumnName)); + mutator.execute(consistencyLevel); + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsUtils.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsUtils.java new file mode 100644 index 000000000..1d0b7e87d --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/pelops/PelopsUtils.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.pelops; + +import java.io.IOException; +import java.net.Socket; +import java.net.UnknownHostException; + +import net.dataforte.cassandra.pool.HostFailoverPolicy; +import net.dataforte.cassandra.pool.PoolConfiguration; + +import org.scale7.cassandra.pelops.SimpleConnectionAuthenticator; +import org.scale7.cassandra.pelops.pool.CommonsBackedPool; +import org.scale7.cassandra.pelops.pool.CommonsBackedPool.Policy; +import org.scale7.cassandra.pelops.pool.IThriftPool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.service.CassandraHost; + +/** + * The Class PelopsUtils. + */ +public class PelopsUtils +{ + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(PelopsUtils.class); + + /** + * Generate pool name. + * + * @param persistenceUnit + * the persistence unit + * @param puProperties + * @return the string + */ + public static String generatePoolName(String node, int port, String keyspace) + { + return node + ":" + port + ":" + keyspace; + } + + /** + * Gets the pool config policy. + * + * @param persistenceUnitMetadata + * the persistence unit metadata + * @param puProperties + * @return the pool config policy + */ + public static Policy getPoolConfigPolicy(CassandraHost cassandraHost) + { + Policy policy = new Policy(); + if (cassandraHost.getMaxActive() > 0) + { + policy.setMaxActivePerNode(cassandraHost.getMaxActive()); + } + if (cassandraHost.getMaxIdle() > 0) + { + policy.setMaxIdlePerNode(cassandraHost.getMaxIdle()); + } + if (cassandraHost.getMinIdle() > 0) + { + policy.setMinIdlePerNode(cassandraHost.getMinIdle()); + } + if (cassandraHost.getMaxTotal() > 0) + { + policy.setMaxTotal(cassandraHost.getMaxTotal()); + } + return policy; + } + + /** + * Gets the pool config policy. + * + * @param persistenceUnitMetadata + * the persistence unit metadata + * @param puProperties + * @return the pool config policy + */ + public static PoolConfiguration setPoolConfigPolicy(CassandraHost cassandraHost, PoolConfiguration prop) + { + int maxActivePerNode = cassandraHost.getMaxActive(); + int maxIdlePerNode = cassandraHost.getMaxIdle(); + int minIdlePerNode = cassandraHost.getMinIdle(); + int maxTotal = cassandraHost.getMaxTotal(); + boolean testOnBorrow = cassandraHost.isTestOnBorrow(); + boolean testWhileIdle = cassandraHost.isTestWhileIdle(); + boolean testOnConnect = cassandraHost.isTestOnConnect(); + boolean testOnReturn = cassandraHost.isTestOnReturn(); + int socketTimeOut = cassandraHost.getSocketTimeOut(); + int maxWaitInMilli = cassandraHost.getMaxWait(); + HostFailoverPolicy paramHostFailoverPolicy = cassandraHost.getHostFailoverPolicy(); + if (maxActivePerNode > 0) + { + prop.setInitialSize(maxActivePerNode); + prop.setMaxActive(maxActivePerNode); + } + if (maxIdlePerNode > 0) + { + prop.setMaxIdle(maxIdlePerNode); + } + if (minIdlePerNode > 0) + { + prop.setMinIdle(minIdlePerNode); + } + if (maxTotal > 0) + { + prop.setMaxActive(maxTotal); + } + prop.setSocketTimeout(socketTimeOut); + prop.setTestOnBorrow(testOnBorrow); + prop.setTestOnConnect(testOnConnect); + prop.setTestOnReturn(testOnReturn); + prop.setTestWhileIdle(testWhileIdle); + prop.setFailoverPolicy(paramHostFailoverPolicy); + prop.setMaxWait(maxWaitInMilli); + return prop; + } + + /** + * If userName and password provided, Method prepares for + * AuthenticationRequest. + * + * @param props + * properties + * + * @return simple authenticator request. returns null if userName/password + * are not provided. + * + */ + public static SimpleConnectionAuthenticator getAuthenticationRequest(String userName, String password) + { + SimpleConnectionAuthenticator authenticator = null; + if (userName != null || password != null) + { + authenticator = new SimpleConnectionAuthenticator(userName, password); + } + return authenticator; + } + + /** + * + * @param host + * @param port + * @return + */ + public static boolean verifyConnection(String host, int port) + { + Socket socket = null; + try + { + socket = new Socket(host, port); + socket.setReuseAddress(true); + socket.setSoLinger(true, 0); + boolean isConnected = socket.isConnected(); + return isConnected; + } + catch (UnknownHostException e) + { + logger.warn("{}:{} is still down", host, port); + return false; + } + catch (IOException e) + { + logger.warn("{}:{} is still down", host, port); + return false; + } + finally + { + try + { + if (socket != null) + { + socket.close(); + } + } + catch (IOException e) + { + logger.warn("{}:{} is still down", host, port); + } + } + } + + /** + * + * @param pool + * @return + */ + public static String getPoolName(IThriftPool pool) + { + org.scale7.cassandra.pelops.Cluster.Node[] nodes = ((CommonsBackedPool) pool).getCluster().getNodes(); + String poolName = PelopsUtils.generatePoolName(nodes[0].getAddress(), ((CommonsBackedPool) pool).getCluster() + .getConnectionConfig().getThriftPort(), ((CommonsBackedPool) pool).getKeyspace()); + return poolName; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassQuery.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassQuery.java new file mode 100644 index 000000000..ee34ae8ee --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassQuery.java @@ -0,0 +1,770 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.query; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Metamodel; + +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.commons.lang.StringUtils; +import org.scale7.cassandra.pelops.Bytes; +import org.scale7.cassandra.pelops.Selector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.index.CassandraIndexHelper; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.kundera.Constants; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.query.KunderaQuery; +import com.impetus.kundera.query.KunderaQuery.FilterClause; +import com.impetus.kundera.query.QueryHandlerException; +import com.impetus.kundera.query.QueryImpl; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * @author vivek.mishra + * + * Query implementation for Cassandra. + */ +public class CassQuery extends QueryImpl +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(CassQuery.class); + + /** The reader. */ + private EntityReader reader; + + private Map externalProperties; + + private boolean isSingleResult = false; + + /** + * Instantiates a new cass query. + * + * @param query + * the query + * @param kunderaQuery + * the kundera query + * @param persistenceDelegator + * the persistence delegator + */ + public CassQuery(String query, KunderaQuery kunderaQuery, PersistenceDelegator persistenceDelegator) + { + super(query, persistenceDelegator); + this.kunderaQuery = kunderaQuery; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.query.QueryImpl#populateEntities(com.impetus.kundera + * .metadata.model.EntityMetadata, com.impetus.kundera.client.Client) + */ + @Override + protected List populateEntities(EntityMetadata m, Client client) + { + if (log.isDebugEnabled()) + { + log.debug("Populating entities for Cassandra query {}.", getJPAQuery()); + } + List result = new ArrayList(); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + externalProperties = ((CassandraClientBase) client).getExternalProperties(); + + // if id attribute is embeddable, it is meant for CQL translation. + // make it independent of embedded stuff and allow even to add non + // composite into where clause and let cassandra complain for it. + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + if (!appMetadata.isNative(getJPAQuery()) && ((CassandraClientBase) client).isCql3Enabled(m)) + { + result = ((CassandraClientBase) client).executeQuery(onQueryOverCQL3(m, client, metaModel, null), + m.getEntityClazz(), null); + } + else + { + if (appMetadata.isNative(getJPAQuery())) + { + result = ((CassandraClientBase) client).executeQuery(appMetadata.getQuery(getJPAQuery()), + m.getEntityClazz(), null); + } + else + { + if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + // Index in Inverted Index table if applicable + boolean useInvertedIndex = CassandraIndexHelper.isInvertedIndexingApplicable(m, + MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())); + Map> ixClause = prepareIndexClause(m, useInvertedIndex); + if (useInvertedIndex && !getKunderaQuery().getFilterClauseQueue().isEmpty()) + { + result = (List) ((CassandraEntityReader) getReader()).readFromIndexTable(m, client, ixClause); + } + else + { + boolean isRowKeyQuery = ixClause.keySet().iterator().next(); + if (!isRowKeyQuery) + { + result = ((CassandraClientBase) client).find(ixClause.get(isRowKeyQuery), m, false, null, + isSingleResult ? 1 : this.maxResult, + getColumnList(m, getKunderaQuery().getResult(), null)); + } + else + { + result = ((CassandraEntityReader) getReader()).handleFindByRange(m, client, result, + ixClause, isRowKeyQuery, getColumnList(m, getKunderaQuery().getResult(), null), + isSingleResult ? 1 : this.maxResult); + } + } + + } + else + { + result = populateUsingLucene(m, client, result, null); + } + } + } + return result; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.query.QueryImpl#recursivelyPopulateEntities(com.impetus + * .kundera.metadata.model.EntityMetadata, + * com.impetus.kundera.client.Client) + */ + @SuppressWarnings("unchecked") + @Override + protected List recursivelyPopulateEntities(EntityMetadata m, Client client) + { + List ls = null; + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + if (appMetadata.isNative(getJPAQuery())) + { + ls = (List) ((CassandraClientBase) client).executeQuery(appMetadata.getQuery(getJPAQuery()), + m.getEntityClazz(), null); + } + else if (!appMetadata.isNative(getJPAQuery()) && ((CassandraClientBase) client).isCql3Enabled(m)) + { + ls = ((CassandraClientBase) client).executeQuery( + onQueryOverCQL3(m, client, metaModel, m.getRelationNames()), m.getEntityClazz(), + m.getRelationNames()); + } + else + { + // Index in Inverted Index table if applicable + boolean useInvertedIndex = CassandraIndexHelper.isInvertedIndexingApplicable(m, + MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())); + Map> ixClause = MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata()) ? prepareIndexClause( + m, useInvertedIndex) : null; + + if (useInvertedIndex && !getKunderaQuery().getFilterClauseQueue().isEmpty()) + { + ls = ((CassandraEntityReader) getReader()).readFromIndexTable(m, client, ixClause); + } + else + { + ((CassandraEntityReader) getReader()).setConditions(ixClause); + ls = reader.populateRelation(m, client, isSingleResult ? 1 : this.maxResult); + } + } + return setRelationEntities(ls, client, m); + } + + /** + * On executeUpdate. + * + * @return zero + */ + @Override + protected int onExecuteUpdate() + { + EntityMetadata m = getEntityMetadata(); + if (KunderaMetadata.INSTANCE.getApplicationMetadata().isNative(getJPAQuery())) + { + ((CassandraClientBase) persistenceDelegeator.getClient(m)).executeQuery(KunderaMetadata.INSTANCE + .getApplicationMetadata().getQuery(getJPAQuery()), m.getEntityClazz(), null); + } + else if (kunderaQuery.isDeleteUpdate()) + { + List result = getResultList(); + return result != null ? result.size() : 0; + } + return 0; + } + + /** + * Gets the column list. + * + * @param m + * the m + * @param results + * the results + * @return the column list + */ + List getColumnList(EntityMetadata m, String[] results, EmbeddableType compoundKey) + { + List columns = new ArrayList(); + if (results != null && results.length > 0) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entity = metaModel.entity(m.getEntityClazz()); + + String keyFieldName = CassandraUtilities.getIdColumnName(m, externalProperties); + for (int i = 1; i < results.length; i++) + { + if (results[i] != null) + { + Attribute attribute = entity.getAttribute(results[i]); + if (attribute == null) + { + throw new QueryHandlerException("column type is null for: " + results); + } + else if (m.getIdAttribute().equals(attribute) && compoundKey != null) + { + Field[] fields = m.getIdAttribute().getBindableJavaType().getDeclaredFields(); + for (Field field : fields) + { + if (!ReflectUtils.isTransientOrStatic(field)) + { + Attribute compositeColumn = compoundKey.getAttribute(field.getName()); + columns.add(((AbstractAttribute) compositeColumn).getJPAColumnName()); + } + } + } + else if (m.getIdAttribute().equals(attribute) && compoundKey == null) + { + columns.add(keyFieldName); + } + else + { + columns.add(((AbstractAttribute) attribute).getJPAColumnName()); + } + } + } + return columns; + } + + if (log.isInfoEnabled()) + { + log.info("No record found, returning null."); + } + return null; + } + + /** + * Prepare index clause. + * + * @param m + * the m + * @param isQueryForInvertedIndex + * the is query for inverted index + * @return the map + */ + Map> prepareIndexClause(EntityMetadata m, boolean isQueryForInvertedIndex) + { + IndexClause indexClause = Selector.newIndexClause(Bytes.EMPTY, maxResult); + List clauses = new ArrayList(); + List expr = new ArrayList(); + + Map> idxClauses = new HashMap>(1); + // check if id column are mixed with other columns or not? + String idColumn = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + boolean idPresent = false; + + if (log.isInfoEnabled()) + { + log.info("Preparing index clause for query {}", getJPAQuery()); + } + + for (Object o : getKunderaQuery().getFilterClauseQueue()) + { + if (o instanceof FilterClause) + { + FilterClause clause = ((FilterClause) o); + // String fieldName = getColumnName(clause.getProperty()); + String fieldName = clause.getProperty(); + // in case id column matches with field name, set it for first + // time. + if (!idPresent && idColumn.equalsIgnoreCase(fieldName)) + { + idPresent = true; + } + + String condition = clause.getCondition(); + Object value = clause.getValue(); + IndexOperator operator = getOperator(condition, idPresent); + + IndexExpression expression = Selector.newIndexExpression(fieldName, operator, + getBytesValue(fieldName, m, value)); + + expr.add(expression); + } + else + { + // Case of AND and OR clause. + String opr = o.toString(); + if (opr.equalsIgnoreCase("or")) + { + log.error("Support for OR clause is not enabled within cassandra."); + throw new QueryHandlerException("Unsupported clause " + opr + " for cassandra."); + } + + } + } + + if (!StringUtils.isBlank(getKunderaQuery().getFilter())) + { + indexClause.setExpressions(expr); + clauses.add(indexClause); + } + idxClauses.put(idPresent, clauses); + + return idxClauses; + } + + /** + * Gets the operator. + * + * @param condition + * the condition + * @param idPresent + * the id present + * @return the operator + */ + private IndexOperator getOperator(String condition, boolean idPresent) + { + if (/* !idPresent && */condition.equals("=")) + { + return IndexOperator.EQ; + } + else if (/* !idPresent && */condition.equals(">")) + { + return IndexOperator.GT; + } + else if (/* !idPresent && */condition.equals("<")) + { + return IndexOperator.LT; + } + else if (condition.equals(">=")) + { + return IndexOperator.GTE; + } + else if (condition.equals("<=")) + { + return IndexOperator.LTE; + } + else + { + + if (!idPresent) + { + throw new UnsupportedOperationException("Condition " + condition + " is not suported in cassandra."); + } + else + { + throw new UnsupportedOperationException("Condition " + condition + + " is not suported for query on row key."); + + } + } + + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#getReader() + */ + @Override + protected EntityReader getReader() + { + if (reader == null) + { + reader = new CassandraEntityReader(getLuceneQueryFromJPAQuery()); + } + + return reader; + } + + /** + * Returns bytes value for given value. + * + * @param jpaFieldName + * field name. + * @param m + * entity metadata + * @param value + * value. + * @return bytes value. + */ + Bytes getBytesValue(String jpaFieldName, EntityMetadata m, Object value) + { + // Column idCol = m.getIdColumn(); + Attribute idCol = m.getIdAttribute(); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entity = metaModel.entity(m.getEntityClazz()); + Field f = null; + boolean isId = false; + if (((AbstractAttribute) idCol).getJPAColumnName().equals(jpaFieldName)) + { + f = (Field) idCol.getJavaMember(); + isId = true; + } + else + { + if (jpaFieldName != null && jpaFieldName.indexOf(Constants.INDEX_TABLE_ROW_KEY_DELIMITER) > 0) + { + String embeddedFieldName = jpaFieldName.substring(0, + jpaFieldName.indexOf(Constants.INDEX_TABLE_ROW_KEY_DELIMITER)); + String columnFieldName = jpaFieldName.substring( + jpaFieldName.indexOf(Constants.INDEX_TABLE_ROW_KEY_DELIMITER) + 1, jpaFieldName.length()); + + Attribute embeddedAttr = entity.getAttribute(embeddedFieldName); + try + { + Class embeddedClass = embeddedAttr.getJavaType(); + if (Collection.class.isAssignableFrom(embeddedClass)) + { + Class genericClass = PropertyAccessorHelper.getGenericClass((Field) embeddedAttr + .getJavaMember()); + f = genericClass.getDeclaredField(columnFieldName); + } + else + { + f = embeddedClass.getDeclaredField(columnFieldName); + } + + } + catch (SecurityException e) + { + log.error("Error while extrating " + jpaFieldName + ", Caused by: ", e); + throw new QueryHandlerException("Error while extrating " + jpaFieldName + "."); + } + catch (NoSuchFieldException e) + { + log.error("Error while extrating " + jpaFieldName + ", Caused by: ", e); + throw new QueryHandlerException("Error while extrating " + jpaFieldName + "."); + } + + } + else + { + String fieldName = m.getFieldName(jpaFieldName); + + Attribute col = entity.getAttribute(fieldName); + // Column col = m.getColumn(jpaFieldName); + if (col == null) + { + throw new QueryHandlerException("column type is null for: " + jpaFieldName); + } + f = (Field) col.getJavaMember(); + } + + } + + // need to do integer.parseInt..as value will be string in case of + // create query. + if (f != null && f.getType() != null) + { + return CassandraUtilities.toBytes(value, f); + } + else + { + log.error("Error while handling data type for " + jpaFieldName + "."); + throw new QueryHandlerException("Field type is null for " + jpaFieldName + "."); + } + } + + /** + * On query over composite columns. + * + * @param m + * the m + * @param client + * the client + * @param metaModel + * the meta model + * @return the list + */ + String onQueryOverCQL3(EntityMetadata m, Client client, MetamodelImpl metaModel, List relations) + { + List result = new ArrayList(); + + // select column will always be of entity field only! + // where clause ordering + + Class compoundKeyClass = m.getIdAttribute().getBindableJavaType(); + EmbeddableType compoundKey = null; + String idColumn; + if (metaModel.isEmbeddable(compoundKeyClass)) + { + compoundKey = metaModel.embeddable(compoundKeyClass); + idColumn = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + } + else + { + idColumn = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + } + StringBuilder builder = new StringBuilder(); + + boolean isPresent = false; + List columns = getColumnList(m, getKunderaQuery().getResult(), compoundKey); + String selectQuery = columns != null && !columns.isEmpty() ? CQLTranslator.SELECT_QUERY + : CQLTranslator.SELECTALL_QUERY; + + + CQLTranslator translator = new CQLTranslator(); + + selectQuery = StringUtils.replace(selectQuery, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), m.getTableName()).toString()); + + builder = CassandraUtilities.appendColumns(builder, columns, selectQuery, translator); + + addWhereClause(builder); + + onCondition(m, metaModel, compoundKey, idColumn, builder, isPresent, translator); + + return builder.toString(); + // onLimit(builder); + + // result = ((CassandraClientBase) + // client).executeQuery(builder.toString(), m.getEntityClazz(), + // relations); + // return result; + } + + /** + * Add provided max result limit. + * + * @param builder + * string builder. + */ + private void onLimit(StringBuilder builder) + { + builder.append(CQLTranslator.LIMIT); + builder.append(isSingleResult ? 1 : this.maxResult); + } + + /** + * On condition. + * + * @param m + * the m + * @param metaModel + * the meta model + * @param keyObj + * the compound key + * @param idColumn + * the id column + * @param builder + * the builder + * @param isPresent + * the is present + * @param translator + * the translator + * @return true, if successful + */ + private boolean onCondition(EntityMetadata m, MetamodelImpl metaModel, EmbeddableType keyObj, String idColumn, + StringBuilder builder, boolean isPresent, CQLTranslator translator) + { + String partitionKey = null; + boolean allowFiltering = false; + for (Object o : getKunderaQuery().getFilterClauseQueue()) + { + if (o instanceof FilterClause) + { + FilterClause clause = ((FilterClause) o); + String fieldName = clause.getProperty(); + String condition = clause.getCondition(); + Object value = clause.getValue(); + + // if compound key field is given in where clause. + isPresent = true; + + if (keyObj != null && idColumn.equals(fieldName)) + { + Field[] fields = m.getIdAttribute().getBindableJavaType().getDeclaredFields(); + for (Field field : fields) + { + if (!ReflectUtils.isTransientOrStatic(field)) + { + Attribute compositeColumn = keyObj.getAttribute(field.getName()); + translator.buildWhereClause(builder, + ((AbstractAttribute) compositeColumn).getJPAColumnName(), field, value); + if (partitionKey == null) + { + partitionKey = compositeColumn.getName(); + } + + if (!allowFiltering) + { + allowFiltering = fieldName.equals(partitionKey); + } + } + } + } + else if (keyObj != null && metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType()) + && StringUtils.contains(fieldName, '.')) + { + // Means it is a case of composite column. + fieldName = fieldName.substring(fieldName.indexOf(".") + 1); + ((AbstractAttribute) keyObj.getAttribute(fieldName)).getJPAColumnName(); + // compositeColumns.add(new + // BasicDBObject(compositeColumn,value)); + translator.buildWhereClause(builder, + ((AbstractAttribute) keyObj.getAttribute(fieldName)).getBindableJavaType(), + ((AbstractAttribute) keyObj.getAttribute(fieldName)).getJPAColumnName(), value, condition); + if (partitionKey == null) + { + partitionKey = keyObj.getAttribute(fieldName).getName(); + } + if (!allowFiltering) + { + allowFiltering = fieldName.equals(partitionKey); + } + } + else if (idColumn.equals(fieldName)) + { + translator.buildWhereClause(builder, + ((AbstractAttribute) m.getIdAttribute()).getBindableJavaType(), + CassandraUtilities.getIdColumnName(m, externalProperties), value, condition); + } + else + { + Metamodel metamodel = KunderaMetadataManager.getMetamodel(m.getPersistenceUnit()); + Attribute attribute = ((MetamodelImpl) metamodel).getEntityAttribute(m.getEntityClazz(), + m.getFieldName(fieldName)); + translator.buildWhereClause(builder, ((AbstractAttribute) attribute).getBindableJavaType(), + fieldName, value, condition); + allowFiltering = true; + } + } + } + + // String last AND clause. + if (isPresent) + { + builder.delete(builder.lastIndexOf(CQLTranslator.AND_CLAUSE), builder.length()); + } + + if (allowFiltering) + { + onLimit(builder); + builder.append(" "); + translator.buildFilteringClause(builder); + } + else + { + onLimit(builder); + } + + return isPresent; + } + + /** + * Adds the where clause. + * + * @param builder + * the builder + */ + void addWhereClause(StringBuilder builder) + { + if (!getKunderaQuery().getFilterClauseQueue().isEmpty()) + { + builder.append(CQLTranslator.ADD_WHERE_CLAUSE); + } + } + + @Override + public void close() + { + // TODO Auto-generated method stub + + } + + @Override + public Iterator iterate() + { + EntityMetadata m = getEntityMetadata(); + Client client = persistenceDelegeator.getClient(m); + externalProperties = ((CassandraClientBase) client).getExternalProperties(); + + if (!MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + throw new UnsupportedOperationException("Scrolling over hbase is unsupported for lucene queries"); + } + + return new ResultIterator(this, m, persistenceDelegeator.getClient(m), this.getReader(), + getFetchSize() != null ? getFetchSize() : this.maxResult); + } + + void setRelationalEntities(List enhanceEntities, Client client, EntityMetadata m) + { + super.setRelationEntities(enhanceEntities, client, m); + } + + @Override + public Object getSingleResult() + { + // to fetch a single result form database. + isSingleResult = true; + List results = getResultList(); + isSingleResult=false; + return results.isEmpty() ? results : results.get(0); + } + +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassandraEntityReader.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassandraEntityReader.java new file mode 100644 index 000000000..45fdae132 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/CassandraEntityReader.java @@ -0,0 +1,326 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.kundera.Constants; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.AbstractEntityReader; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.query.QueryHandlerException; + +/** + * The Class CassandraEntityReader. + * + * @author vivek.mishra + */ +public class CassandraEntityReader extends AbstractEntityReader implements EntityReader +{ + + /** + * + */ + private static final String MIN_ = "min"; + + /** + * + */ + private static final String MAX_ = "max"; + + /** The conditions. */ + Map> conditions = new HashMap>(); + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(CassandraEntityReader.class); + + /** + * Instantiates a new cassandra entity reader. + * + * @param luceneQuery + * the lucene query + */ + public CassandraEntityReader(String luceneQuery) + { + this.luceneQueryFromJPAQuery = luceneQuery; + } + + /** + * Instantiates a new cassandra entity reader. + */ + public CassandraEntityReader() + { + + } + + @Override + public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client) + { + return super.findById(primaryKey, m, client); + } + + /** + * Method responsible for reading back entity and relations using secondary + * indexes(if it holds any relation), else retrieve row keys using lucene. + * + * @param m + * entity meta data + * @param relationNames + * relation names + * @param isParent + * if entity is not holding any relation. + * @param client + * client instance + * @return list of wrapped enhance entities. + */ + + @Override + public List populateRelation(EntityMetadata m, Client client, int maxResults) + { + if(log.isInfoEnabled()) + { + log.info("On populate relation via JPQL"); + } + List ls = null; + List relationNames = m.getRelationNames(); + boolean isParent = m.isParent(); + + boolean isRowKeyQuery = conditions != null ? conditions.keySet().iterator().next() : false; + + // If Query is not for find by range. + if (!isRowKeyQuery) + { + // If holding associations. + if (!isParent) + { + // In case need to use secondary indexes. + if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + + ls = ((CassandraClientBase) client).find(m, relationNames, this.conditions.get(isRowKeyQuery), 100, + null); + } + else + { + // prepare lucene query and find. + Set rSet = fetchDataFromLucene(client); + + try + { + ls = (List) ((CassandraClientBase) client).find(m.getEntityClazz(), + relationNames, true, m, rSet.toArray(new String[] {})); + } + catch (Exception e) + { + log.error("Error while executing handleAssociation for cassandra, Caused by: ", e); + throw new QueryHandlerException(e); + } + } + } + else + { + if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + // in case need to search on secondry columns and it is not + // set + // to true! + ls = ((CassandraClientBase) client).find(this.conditions.get(isRowKeyQuery), m, true, + m.getRelationNames(), 100, null); + } + else + { + ls = onAssociationUsingLucene(m, client, ls); + } + } + } + else + { + // List results = new ArrayList(); + ls = handleFindByRange(m, client, ls, conditions, isRowKeyQuery, null,maxResults); + // ls = (List) results; + } + return ls; + } + + /** + * Handle find by range. + * + * @param m + * the m + * @param client + * the client + * @param result + * the result + * @param ixClause + * the ix clause + * @param isRowKeyQuery + * the is row key query + * @param columns + * @return the list + */ + public List handleFindByRange(EntityMetadata m, Client client, List result, + Map> ixClause, boolean isRowKeyQuery, List columns, int maxResults) + { + List expressions = ixClause.get(isRowKeyQuery).get(0).getExpressions(); + + if (expressions == null) + { + return null; + } + + Map rowKeys = getRowKeyValue(expressions, + ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName()); + + byte[] minValue = rowKeys.get(MIN_); + byte[] maxVal = rowKeys.get(MAX_); + + try + { + + result = ((CassandraClientBase) client).findByRange(minValue, maxVal, m, m.getRelationNames() != null + && !m.getRelationNames().isEmpty(), m.getRelationNames(), columns, expressions, maxResults); + } + catch (Exception e) + { + log.error("Error while executing find by range, Caused by: ", e); + throw new QueryHandlerException(e); + } + return result; + } + + public List readFromIndexTable(EntityMetadata m, Client client, + Map> indexClauseMap) + { + + List searchResults = new ArrayList(); + List primaryKeys = new ArrayList(); + + String columnFamilyName = m.getTableName() + Constants.INDEX_TABLE_SUFFIX; + searchResults = ((CassandraClientBase) client).searchInInvertedIndex(columnFamilyName, m, indexClauseMap); + + Map embeddedColumns = new HashMap(); + for (SearchResult searchResult : searchResults) + { + if (searchResult.getEmbeddedColumnValues() != null) + { + for (String embeddedColVal : searchResult.getEmbeddedColumnValues()) + { + if (embeddedColVal != null) + { + StringBuilder strBuilder = new StringBuilder(embeddedColVal); + strBuilder.append("|"); + strBuilder.append(searchResult.getPrimaryKey().toString()); + embeddedColumns.put(strBuilder.toString(), searchResult.getPrimaryKey().toString()); + } + } + } + } + + List enhanceEntityList = new ArrayList(); + if (embeddedColumns != null && !embeddedColumns.isEmpty()) + { + enhanceEntityList = client.find(m.getEntityClazz(), embeddedColumns); + } + else + { + for (SearchResult searchResult : searchResults) + { + primaryKeys.add(searchResult.getPrimaryKey()); + } + enhanceEntityList = (List) ((CassandraClientBase) client).find(m.getEntityClazz(), + m.getRelationNames(), true, m, primaryKeys.toArray(new String[] {})); + } + + return enhanceEntityList; + } + + /** + * Method to set indexcluase conditions. + * + * @param conditions + * index conditions. + */ + public void setConditions(Map> conditions) + { + this.conditions = conditions; + } + + /** + * Returns list of row keys. First element will be min value and second will + * be major value. + * + * @param expressions + * @param primaryKeyName + * @return + */ + Map getRowKeyValue(List expressions, String primaryKeyName) + { + Map rowKeys = new HashMap(); + + List rowExpressions = new ArrayList(); + + if (expressions != null) + { + for (IndexExpression e : expressions) + { + + if (primaryKeyName.equals(new String(e.getColumn_name()))) + { + IndexOperator operator = e.op; + if (operator.equals(IndexOperator.LTE) || operator.equals(IndexOperator.LT)) + { + rowKeys.put(MAX_, e.getValue()); + rowExpressions.add(e); + } + else if (operator.equals(IndexOperator.GTE) || operator.equals(IndexOperator.GT)) + { + rowKeys.put(MIN_, e.getValue()); + rowExpressions.add(e); + } + else if (operator.equals(IndexOperator.EQ)) + { + + rowKeys.put(MAX_, e.getValue()); + rowKeys.put(MIN_, e.getValue()); + rowExpressions.add(e); + } + + } + + } + expressions.removeAll(rowExpressions); + } + return rowKeys; + + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/ResultIterator.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/ResultIterator.java new file mode 100644 index 000000000..f2ef661a8 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/query/ResultIterator.java @@ -0,0 +1,541 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.query; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.persistence.PersistenceException; +import javax.persistence.Query; +import javax.persistence.metamodel.EmbeddableType; + +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.commons.lang.StringUtils; +import org.scale7.cassandra.pelops.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.index.CassandraIndexHelper; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.query.IResultIterator; +import com.impetus.kundera.query.KunderaQuery.FilterClause; +import com.impetus.kundera.query.QueryImpl; + +/** + * @author vivek.mishra . + * + * Implementation of Cassandra result iteration. + * + * TODO::: Need to add support for relational entities and a junit for + * Composite key test + */ +class ResultIterator implements IResultIterator +{ + private static Logger log = LoggerFactory.getLogger(ResultIterator.class); + + private CassQuery query; + + private EntityMetadata entityMetadata; + + private Client client; + + private EntityReader reader; + + private int maxResult = 1; + + private List results; + + private byte[] start; + + private static final String MIN_ = "min"; + + private static final String MAX_ = "max"; + + // private boolean isValidated; + + private int fetchSize; + + private int count; + + private boolean scrollComplete; + + private Map externalProperties; + + private E current; + + /** + * Constructor with parameters + * + * @param query + * @param m + * @param client + * @param reader + * @param fetchSize + */ + ResultIterator(final Query query, final EntityMetadata m, final Client client, final EntityReader reader, + final int fetchSize) + { + this.client = client; + this.query = (CassQuery) query; + this.entityMetadata = m; + this.reader = reader; + scrollComplete = false; + this.fetchSize = fetchSize; + + } + + @Override + public boolean hasNext() + { + if (checkOnFetchSize()) + { + onCheckRelation(); + if (!checkOnEmptyResult()) + { + scrollComplete = true; + return false; + } + + return true; + } + + return false; + } + + @Override + public E next() + { + if (current != null && checkOnEmptyResult() && current.equals(results.get(results.size() - 1))) + { + hasNext(); + } + + if (scrollComplete) + { + throw new NoSuchElementException("Nothing to scroll further for:" + entityMetadata.getEntityClazz()); + } + + E lastFetchedEntity = getEntity(results.get(results.size() - 1)); + start = lastFetchedEntity != null ? idValueInByteArr() : null; + current = getEntity(results.get(results.size() - 1)); + + return current; + + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove method is not supported over pagination"); + } + + @Override + public List next(int chunkSize) + { + throw new UnsupportedOperationException("fetch in chunks is not yet supported"); + } + + /** + * Check on fetch size. returns true, if count on fetched rows is less than + * fetch size. + * + * @return + */ + private boolean checkOnFetchSize() + { + if (count++ < fetchSize) + { + return true; + } + count = 0; + scrollComplete = true; + return false; + } + + /** + * on check relation event, invokes populate entities and set relational + * entities, in case relations are present. + */ + private void onCheckRelation() + { + try + { + results = populateEntities(entityMetadata, client); + + if (entityMetadata.isRelationViaJoinTable() + || (entityMetadata.getRelationNames() != null && !(entityMetadata.getRelationNames().isEmpty()))) + { + query.setRelationalEntities(results, client, entityMetadata); + } + } + catch (Exception e) + { + throw new PersistenceException("Error while scrolling over results, Caused by :.", e); + } + + } + + /** + * Method parse provided JPQL query into: 1. CQL3 query, in case cql3 is + * enabled or is a native query. 2. list of index clause, if cql2 is + * enabled. Then executes query for given min & max values for scrolling + * over results. + * + * @param m + * entity metadata + * @param client + * client + * @return list of database values wrapped into entities. + * @throws Exception + * throws exception, in case of run time error. + */ + private List populateEntities(EntityMetadata m, Client client) throws Exception + { + if (log.isDebugEnabled()) + { + log.debug("Populating entities for Cassandra query {}.", ((QueryImpl) query).getJPAQuery()); + } + List result = new ArrayList(); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + externalProperties = ((CassandraClientBase) client).getExternalProperties(); + + // if id attribute is embeddable, it is meant for CQL translation. + // make it independent of embedded stuff and allow even to add non + // composite into where clause and let cassandra complain for it. + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + if (!appMetadata.isNative(((QueryImpl) query).getJPAQuery()) && ((CassandraClientBase) client).isCql3Enabled(m)) + { + String parsedQuery = query.onQueryOverCQL3(m, client, metaModel, null); + + parsedQuery = appendWhereClauseWithScroll(parsedQuery); + results = parsedQuery != null ? ((CassandraClientBase) client).executeQuery(parsedQuery, + m.getEntityClazz(), m.getRelationNames()) : null; + + } + else + { + if (appMetadata.isNative(((QueryImpl) query).getJPAQuery())) + { + final String nativeQuery = appendWhereClauseWithScroll(((QueryImpl) query).getJPAQuery()); + results = nativeQuery != null ? ((CassandraClientBase) client).executeQuery(nativeQuery, + m.getEntityClazz(), null) : null; + } + else + { + // Index in Inverted Index table if applicable + boolean useInvertedIndex = CassandraIndexHelper.isInvertedIndexingApplicable(m, + MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())); + Map> ixClause = query.prepareIndexClause(m, useInvertedIndex); + if (useInvertedIndex && !((QueryImpl) query).getKunderaQuery().getFilterClauseQueue().isEmpty()) + { + result = (List) ((CassandraEntityReader) this.reader).readFromIndexTable(m, client, ixClause); + } + else + { + boolean isRowKeyQuery = ixClause.keySet().iterator().next(); + + List expressions = !ixClause.get(isRowKeyQuery).isEmpty() ? ixClause + .get(isRowKeyQuery).get(0).getExpressions() : null; + + Map rowKeys = ((CassandraEntityReader) this.reader).getRowKeyValue(expressions, + ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName()); + + byte[] minValue = start == null ? rowKeys.get(MIN_) : start; + byte[] maxVal = rowKeys.get(MAX_); + + results = ((CassandraClientBase) client).findByRange(minValue, maxVal, m, + m.getRelationNames() != null && !m.getRelationNames().isEmpty(), m.getRelationNames(), + query.getColumnList(m, ((QueryImpl) query).getKunderaQuery().getResult(), null), + expressions, maxResult); + + if (maxResult == 1) + { + maxResult++; + } + else if (maxResult > 1 && checkOnEmptyResult() && maxResult != results.size()) + { + // means iterating over last record only, so need for + // database trip anymore!. + results = null; + } + + } + + } + } + + return results; + } + + /** + * Appends where claues and prepare for next fetch. Method to be called in + * case cql3 enabled. + * + * @param parsedQuery + * parsed query. + * + * @return cql3 query to be executed. + */ + private String appendWhereClauseWithScroll(String parsedQuery) + { + String queryWithoutLimit = parsedQuery.replaceAll( + parsedQuery.substring(parsedQuery.lastIndexOf(CQLTranslator.LIMIT), parsedQuery.length()), ""); + + CQLTranslator translator = new CQLTranslator(); + + final String tokenCondition = prepareNext(translator, queryWithoutLimit); + + boolean tokenPresent = queryWithoutLimit.indexOf(CQLTranslator.TOKEN) > -1; + + StringBuilder builder = new StringBuilder(tokenPresent ? tokenCondition : queryWithoutLimit); + + if (!tokenPresent && tokenCondition != null) + { + if (query.getKunderaQuery().getFilterClauseQueue().isEmpty()) + { + builder.append(CQLTranslator.ADD_WHERE_CLAUSE); + } + else + { + builder.append(CQLTranslator.AND_CLAUSE); + } + builder.append(tokenCondition); + } + + String replaceQuery = replaceAndAppendLimit(builder.toString()); + builder.replace(0, builder.toString().length(), replaceQuery); + translator.buildFilteringClause(builder); + + // in case of fetch by ID, token condition will be null and results will + // not be empty. + return checkOnEmptyResult() && tokenCondition == null ? null : builder.toString(); + } + + /** + * Replace and append limit. + * + * @param parsedQuery + * parsed cql3 query. + * + * @return cql3 query appended with limit clause. + */ + private String replaceAndAppendLimit(String parsedQuery) + { + // String queryWithoutLimit = parsedQuery.replaceAll( + // parsedQuery.substring(parsedQuery.lastIndexOf(CQLTranslator.LIMIT), + // parsedQuery.length()), ""); + StringBuilder builder = new StringBuilder(parsedQuery); + onLimit(builder); + parsedQuery = builder.toString(); + return parsedQuery; + } + + /** + * Append limit to sql3 query. + * + * @param builder + * builder instance. + */ + private void onLimit(StringBuilder builder) + { + builder.append(CQLTranslator.LIMIT); + builder.append(this.maxResult); + } + + /** + * Parse and append cql3 token function for iter.next() call. + * + * @param translator + * cql translator. + * + * @return parsed/append cql3 query. + */ + private String prepareNext(CQLTranslator translator, String query) + { + if (checkOnEmptyResult()) + { + String idName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName(); + Map filterOnId = getConditionOnIdColumn(idName); + + if (filterOnId.get(true) != null) + { + String condition = filterOnId.get(true); + // means id clause present in query. + // now if id attribute is embeddable then fetch partition key + // for token + // if condition is with equals then no need to go for another + // fetch. + + if (condition.equals("=")) + { + // no need to fetch another record, as there will be only + // one + return null; + } + else if (condition.endsWith(">") || condition.equals(">=")) + { + query = replaceAppliedToken(query); + return query; + } + } + + // Means there is an previous entity. + Object entity = results.get(results.size() - 1); + Class idClazz = ((AbstractAttribute) entityMetadata.getIdAttribute()).getBindableJavaType(); + Object id = PropertyAccessorHelper.getId(entity, entityMetadata); + StringBuilder builder = new StringBuilder(CQLTranslator.TOKEN); + translator + .appendColumnName(builder, CassandraUtilities.getIdColumnName(entityMetadata, externalProperties)/* idName */); + builder.append(CQLTranslator.CLOSE_BRACKET); + builder.append(" > "); + builder.append(CQLTranslator.TOKEN); + translator.appendValue(builder, idClazz, id, false); + builder.append(CQLTranslator.CLOSE_BRACKET); + return builder.toString(); + } + return null; + } + + private Map getConditionOnIdColumn(String idColumn) + { + + Map filterIdResult = new HashMap(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + EmbeddableType keyObj = null; + if (metaModel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType())) + { + keyObj = metaModel.embeddable(entityMetadata.getIdAttribute().getBindableJavaType()); + } + + boolean isPresent = false; + for (Object o : query.getKunderaQuery().getFilterClauseQueue()) + { + if (o instanceof FilterClause) + { + FilterClause clause = ((FilterClause) o); + String fieldName = clause.getProperty(); + String condition = clause.getCondition(); + Object value = clause.getValue(); + + if (keyObj != null && fieldName.equals(idColumn) + || (keyObj != null && StringUtils.contains(fieldName, '.')) || (idColumn.equals(fieldName))) + { + filterIdResult.put(true, condition); + break; + } + } + } + + return filterIdResult; + } + + /** + * id attribute's value in byte[] + * + * @return id attribute's value in byte[] + */ + private byte[] idValueInByteArr() + { + Object entity = results.get(results.size() - 1); + Object id = PropertyAccessorHelper.getId(entity, entityMetadata); + String idName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName(); + Class idClazz = ((AbstractAttribute) entityMetadata.getIdAttribute()).getBindableJavaType(); + Bytes bytes = query.getBytesValue(idName, entityMetadata, id); + + return bytes.toByteArray(); + + } + + /** + * check if result list is null or empty. Returns true, if it is not empty + * or null. + * + * @return boolean value (true/false). + * + */ + private boolean checkOnEmptyResult() + { + return results != null && !results.isEmpty(); + } + + /** + * Extract wrapped entity object from enhanced entity. + * + * @param entity + * enhanced entity. + * + * @return returns extracted instance of E. + */ + private E getEntity(Object entity) + { + return (E) (entity.getClass().isAssignableFrom(EnhanceEntity.class) ? ((EnhanceEntity) entity).getEntity() + : entity); + } + + private String replaceAppliedToken(String query) + { + final String tokenRegex = "\\btoken\\("; + final String pattern = "#TOKENKUNDERA#"; // need to replace with this as + // pattern matcher was + // returning false. + query = query.replaceAll(tokenRegex, pattern); + + if (query.indexOf(pattern) > -1) // Means token( has been present and + // replaced. + { + CQLTranslator translator = new CQLTranslator(); + + int closingIndex = query.indexOf(CQLTranslator.CLOSE_BRACKET, query.lastIndexOf(pattern)); + + String object = query.substring(query.lastIndexOf(pattern) + pattern.length(), closingIndex); + + Object entity = results.get(results.size() - 1); + Class idClazz = ((AbstractAttribute) entityMetadata.getIdAttribute()).getBindableJavaType(); + Object id = PropertyAccessorHelper.getId(entity, entityMetadata); + StringBuilder builder = new StringBuilder(); + + translator.appendValue(builder, idClazz, id, false); + + query = query.replaceAll(pattern + object, pattern + builder.toString()); + query = query.replaceAll(pattern, CQLTranslator.TOKEN); + } + + return query; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraSchemaManager.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraSchemaManager.java new file mode 100644 index 000000000..7ad633eac --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraSchemaManager.java @@ -0,0 +1,2019 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.schemamanager; + +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.Embeddable; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.db.marshal.ListType; +import org.apache.cassandra.db.marshal.MapType; +import org.apache.cassandra.db.marshal.SetType; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.locator.NetworkTopologyStrategy; +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TBinaryProtocol; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.commons.lang.StringUtils; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.TFramedTransport; +import org.apache.thrift.transport.TSocket; +import org.apache.thrift.transport.TTransport; +import org.apache.thrift.transport.TTransportException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.config.CassandraPropertyReader.CassandraSchemaMetadata; +import com.impetus.client.cassandra.index.CassandraIndexHelper; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.kundera.Constants; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema.DataCenter; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema.Table; +import com.impetus.kundera.configure.schema.CollectionColumnInfo; +import com.impetus.kundera.configure.schema.ColumnInfo; +import com.impetus.kundera.configure.schema.EmbeddedColumnInfo; +import com.impetus.kundera.configure.schema.IndexInfo; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.TableInfo; +import com.impetus.kundera.configure.schema.api.AbstractSchemaManager; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.utils.KunderaCoreUtils; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * Manages auto schema operation defined in {@code ScheamOperationType}. + * + * @author Kuldeep.kumar + * + */ +public class CassandraSchemaManager extends AbstractSchemaManager implements SchemaManager +{ + + private static final String STANDARDCOLUMNFAMILY = "Standard"; + + /** + * Cassandra client variable holds the client. + */ + private Cassandra.Client cassandra_client; + + private String cql_version = CassandraConstants.CQL_VERSION_2_0; + + /** + * logger used for logging statement. + */ + private static final Logger log = LoggerFactory.getLogger(CassandraSchemaManager.class); + + /** The csmd. */ + private CassandraSchemaMetadata csmd = CassandraPropertyReader.csmd; + + /** The tables. */ + private List tables; + + /** + * Instantiates a new cassandra schema manager. + * + * @param clientFactory + * the configured client clientFactory + * @param puProperties + */ + public CassandraSchemaManager(String clientFactory, Map puProperties) + { + super(clientFactory, puProperties); + } + + @Override + /** + * Export schema handles the handleOperation method. + */ + public void exportSchema(final String persistenceUnit, List schemas) + { + cql_version = externalProperties != null ? (String) externalProperties.get(CassandraConstants.CQL_VERSION) + : CassandraConstants.CQL_VERSION_2_0; + super.exportSchema(persistenceUnit, schemas); + } + + /** + * drop schema method drop the table from keyspace. + * + */ + public void dropSchema() + { + if (operation != null && operation.equalsIgnoreCase("create-drop")) + { + try + { + cassandra_client.set_keyspace(databaseName); + for (TableInfo tableInfo : tableInfos) + { + dropColumnFamily(tableInfo); + } + } + catch (Exception ex) + { + log.error("Error during dropping schema in cassandra, Caused by: .", ex); + throw new SchemaGenerationException(ex, "Cassandra"); + } + } + cassandra_client = null; + } + + /** + * Drops column family specified in table info. + * + * @param tableInfo + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private void dropColumnFamily(TableInfo tableInfo) throws Exception + { + if (containsCompositeKey(tableInfo)) + { + dropTableUsingCql(tableInfo); + } + else + { + cassandra_client.system_drop_column_family(tableInfo.getTableName()); + } + } + + /** + * create_drop method creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create_drop(List tableInfos) + { + create(tableInfos); + } + + /** + * Creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create(List tableInfos) + { + try + { + createOrUpdate(tableInfos); + } + catch (Exception ex) + { + throw new PropertyAccessException(ex); + } + } + + /** + * Creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + * @throws TimedOutException + * @throws UnavailableException + */ + private void createOrUpdate(List tableInfos) throws Exception + { + KsDef ksDef = onCreateKeyspace(); // create keyspace event + createColumnFamilies(tableInfos, ksDef); // create column family + // event. + } + + private KsDef onCreateKeyspace() throws Exception + { + try + { + createKeyspace(); + } + catch (InvalidRequestException irex) + { + // Ignore and add a log.debug + } + // keyspace already exists. + cassandra_client.set_keyspace(databaseName); + return cassandra_client.describe_keyspace(databaseName); + } + + /** + * Creates keyspace. + * + * @return + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private KsDef createKeyspace() throws Exception + { + Map strategy_options = new HashMap(); + List cfDefs = new ArrayList(); + KsDef ksDef = new KsDef(databaseName, csmd.getPlacement_strategy(databaseName), cfDefs); + setProperties(ksDef, strategy_options); + ksDef.setStrategy_options(strategy_options); + cassandra_client.system_add_keyspace(ksDef); + return ksDef; + } + + /** + * + * @param tableInfos + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + * @throws UnsupportedEncodingException + * @throws NotFoundException + * @throws UnavailableException + * @throws TimedOutException + */ + private void createColumnFamilies(List tableInfos, KsDef ksDef) throws Exception + { + for (TableInfo tableInfo : tableInfos) + { + createOrUpdateColumnFamily(tableInfo, ksDef); + + // Create Index Table if required + createInvertedIndexTable(tableInfo); + + } + } + + /** + * + * @param tableInfo + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + * @throws NotFoundException + * @throws UnsupportedEncodingException + * @throws UnavailableException + * @throws TimedOutException + */ + private void createOrUpdateColumnFamily(TableInfo tableInfo, KsDef ksDef) throws Exception + { + MetaDataHandler handler = new MetaDataHandler(); + if (containsCompositeKey(tableInfo)) + { + validateCompoundKey(tableInfo); + onCompoundKey(tableInfo, ksDef); + + // After successful schema operation, perform index creation. + createIndexUsingCql(tableInfo); + } + else if (containsCollectionColumns(tableInfo)) + { + createOrUpdateUsingCQL3(tableInfo, ksDef); + createIndexUsingCql(tableInfo); + } + else + { + CfDef cf_def = handler.getTableMetadata(tableInfo); + try + { + cassandra_client.system_add_column_family(cf_def); + } + catch (InvalidRequestException irex) + { + updateExistingColumnFamily(tableInfo, ksDef, irex); + } + } + } + + /** + * Creates (or updates) a column family definition using CQL 3 + * Should replace onCompoundKey + * @param tableInfo + * @param ksDef + * @throws Exception + */ + private void createOrUpdateUsingCQL3(TableInfo tableInfo, KsDef ksDef) throws Exception + { + CQLTranslator translator = new CQLTranslator(); + String columnFamilyQuery = CQLTranslator.CREATE_COLUMNFAMILY_QUERY; + columnFamilyQuery = StringUtils.replace(columnFamilyQuery, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), tableInfo.getTableName()).toString()); + + List columns = tableInfo.getColumnMetadatas(); + + StringBuilder queryBuilder = new StringBuilder(); + + // For normal columns + onCompositeColumns(translator, columns, queryBuilder, null); + onCollectionColumns(translator, tableInfo.getCollectionColumnMetadatas(), queryBuilder); + + // ideally it will always be one as more super column families + // are not allowed with compound/composite key. + List compositeColumns = tableInfo.getEmbeddedColumnMetadatas(); + EmbeddableType compoEmbeddableType = null; + if(! compositeColumns.isEmpty()) + { + compoEmbeddableType = compositeColumns.get(0).getEmbeddable(); + onCompositeColumns(translator, compositeColumns.get(0).getColumns(), queryBuilder, columns); + } + else + { + String dataType = CassandraValidationClassMapper.getValidationClass(tableInfo.getTableIdType(), true); + String cqlType = translator.getCQLType(dataType); + translator.appendColumnName(queryBuilder, tableInfo.getIdColumnName(), cqlType); + queryBuilder.append(" ,"); + } + + queryBuilder = stripLastChar(columnFamilyQuery, queryBuilder); + + // append primary key clause + queryBuilder.append(translator.ADD_PRIMARYKEY_CLAUSE); + + Field[] fields = tableInfo.getTableIdType().getDeclaredFields(); + + // To ensure field ordering + if(compoEmbeddableType != null) + { + StringBuilder primaryKeyBuilder = new StringBuilder(); + appendPrimaryKey(translator, compoEmbeddableType, fields, primaryKeyBuilder); + // should not be null. + primaryKeyBuilder.deleteCharAt(primaryKeyBuilder.length() - 1); + queryBuilder = new StringBuilder(StringUtils.replace(queryBuilder.toString(), CQLTranslator.COLUMNS, + primaryKeyBuilder.toString())); + } + else + { + queryBuilder = new StringBuilder(StringUtils.replace(queryBuilder.toString(), CQLTranslator.COLUMNS, + tableInfo.getIdColumnName())); + } + + // set column family properties defined in configuration property/xml + // files. + setColumnFamilyProperties(null, getColumnFamilyProperties(tableInfo), queryBuilder); + + try + { + cassandra_client.set_cql_version(CassandraConstants.CQL_VERSION_3_0); + cassandra_client.set_keyspace(databaseName); + cassandra_client.execute_cql3_query( + ByteBuffer.wrap(queryBuilder.toString().getBytes(Constants.CHARSET_UTF8)), Compression.NONE, + ConsistencyLevel.ONE); + } + catch (InvalidRequestException irex) + { + updateExistingColumnFamily(tableInfo, ksDef, irex); + } + + } + + private boolean containsCollectionColumns(TableInfo tableInfo) + { + return !tableInfo.getCollectionColumnMetadatas().isEmpty(); + } + + private boolean containsCompositeKey(TableInfo tableInfo) + { + return tableInfo.getTableIdType() != null && tableInfo.getTableIdType().isAnnotationPresent(Embeddable.class); + } + + private void updateExistingColumnFamily(TableInfo tableInfo, KsDef ksDef, InvalidRequestException irex) + throws Exception + { + StringBuilder builder = new StringBuilder("Cannot add already existing column family "); + + if (irex.getWhy() != null && irex.getWhy().contains(builder.toString())) + { + SchemaOperationType operationType = SchemaOperationType.getInstance(operation); + switch (operationType) + { + case create: + handleCreate(tableInfo, ksDef); + + case createdrop: + handleCreate(tableInfo, ksDef); + break; + + case update: + if (isCql3Enabled(tableInfo)) + { + for (ColumnInfo column : tableInfo.getColumnMetadatas()) + { + addColumnToTable(tableInfo, column); + } + } + updateTable(ksDef, tableInfo); + break; + + default: + break; + } + } + else + { + log.error("Error occurred while creating table{}, Caused by: .", tableInfo.getTableName(), irex); + throw new SchemaGenerationException("Error occurred while creating table " + tableInfo.getTableName(), + irex, "Cassandra", databaseName); + } + } + + private void handleCreate(TableInfo tableInfo, KsDef ksDef) throws Exception + { + if (containsCompositeKey(tableInfo)) + { + validateCompoundKey(tableInfo); + // First drop existing column family. + dropTableUsingCql(tableInfo); + } + else + { + onDrop(tableInfo); + } + createOrUpdateColumnFamily(tableInfo, ksDef); + } + + private void onDrop(TableInfo tableInfo) throws Exception + { + dropColumnFamily(tableInfo); + dropInvertedIndexTable(tableInfo); + } + + /** + * update method update schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void update(List tableInfos) + { + try + { + createOrUpdate(tableInfos); + } + catch (Exception ex) + { + log.error("Error occurred while creating {}, Caused by: .", databaseName, ex); + throw new SchemaGenerationException(ex); + } + } + + /** + * validate method validate schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void validate(List tableInfos) + { + try + { + KsDef ksDef = cassandra_client.describe_keyspace(databaseName); + onValidateTables(tableInfos, ksDef); + } + catch (Exception ex) + { + log.error("Error occurred while validating {}, Caused by: .", databaseName, ex); + throw new SchemaGenerationException(ex); + } + } + + /** + * initiate client method initiates the client. + * + * @return boolean value ie client started or not. + * + */ + protected boolean initiateClient() + { + Throwable message = null; + for (String host : hosts) + { + if (host == null || !StringUtils.isNumeric(port) || port.isEmpty()) + { + log.error("Host or port should not be null, Port should be numeric."); + throw new IllegalArgumentException("Host or port should not be null, Port should be numeric."); + } + TSocket socket = new TSocket(host, Integer.parseInt(port)); + TTransport transport = new TFramedTransport(socket); + TProtocol protocol = new TBinaryProtocol(transport); + cassandra_client = new Cassandra.Client(protocol); + try + { + if (!socket.isOpen()) + { + socket.open(); + } + return true; + } + catch (TTransportException e) + { + message = e; + log.warn("Error while opening socket for host {}, skipping for next available node ", host); + } + catch (NumberFormatException e) + { + log.error("Error during creating schema in cassandra, Caused by: .", e); + throw new SchemaGenerationException(e, "Cassandra"); + } + } + throw new SchemaGenerationException("Error while opening socket, Caused by: .", message, "Cassandra"); + } + + /** + * On compound key. + * + * @param tableInfo + * the table infos + * @throws TimedOutException + * @throws UnavailableException + * @throws InvalidRequestException + * the invalid request exception + * @throws TException + * the t exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void onCompoundKey(TableInfo tableInfo, KsDef ksDef) throws Exception + { + CQLTranslator translator = new CQLTranslator(); + String columnFamilyQuery = CQLTranslator.CREATE_COLUMNFAMILY_QUERY; + columnFamilyQuery = StringUtils.replace(columnFamilyQuery, CQLTranslator.COLUMN_FAMILY, + translator.ensureCase(new StringBuilder(), tableInfo.getTableName()).toString()); + + List columns = tableInfo.getColumnMetadatas(); + + StringBuilder queryBuilder = new StringBuilder(); + + // for normal columns + onCompositeColumns(translator, columns, queryBuilder, null); + + // ideally it will always be one as more super column families + // are not allowed with compound/composite key. + + List compositeColumns = tableInfo.getEmbeddedColumnMetadatas(); + EmbeddableType compoEmbeddableType = compositeColumns.get(0).getEmbeddable(); + + // for composite columns + onCompositeColumns(translator, compositeColumns.get(0).getColumns(), queryBuilder, columns); + + queryBuilder = stripLastChar(columnFamilyQuery, queryBuilder); + + // append primary key clause + + queryBuilder.append(translator.ADD_PRIMARYKEY_CLAUSE); + + Field[] fields = tableInfo.getTableIdType().getDeclaredFields(); + + StringBuilder primaryKeyBuilder = new StringBuilder(); + + // To ensure field ordering + appendPrimaryKey(translator, compoEmbeddableType, fields, primaryKeyBuilder); + + // should not be null. + primaryKeyBuilder.deleteCharAt(primaryKeyBuilder.length() - 1); + + queryBuilder = new StringBuilder(StringUtils.replace(queryBuilder.toString(), CQLTranslator.COLUMNS, + primaryKeyBuilder.toString())); + + // set column family properties defined in configuration property/xml + // files. + setColumnFamilyProperties(null, getColumnFamilyProperties(tableInfo), queryBuilder); + + try + { + cassandra_client.set_cql_version(CassandraConstants.CQL_VERSION_3_0); + cassandra_client.set_keyspace(databaseName); + cassandra_client.execute_cql3_query( + ByteBuffer.wrap(queryBuilder.toString().getBytes(Constants.CHARSET_UTF8)), Compression.NONE, + ConsistencyLevel.ONE); + } + catch (InvalidRequestException irex) + { + updateExistingColumnFamily(tableInfo, ksDef, irex); + } + + } + + private void appendPrimaryKey(CQLTranslator translator, EmbeddableType compoEmbeddableType, Field[] fields, + StringBuilder primaryKeyBuilder) + { + for (Field f : fields) + { + if (!ReflectUtils.isTransientOrStatic(f)) + { + Attribute attribute = compoEmbeddableType.getAttribute(f.getName()); + translator.appendColumnName(primaryKeyBuilder, ((AbstractAttribute) attribute).getJPAColumnName()); + primaryKeyBuilder.append(" ,"); + } + } + } + + private StringBuilder stripLastChar(String columnFamilyQuery, StringBuilder queryBuilder) + { + // strip last ",". + if (queryBuilder.length() > 0) + { + queryBuilder.deleteCharAt(queryBuilder.length() - 1); + + columnFamilyQuery = StringUtils.replace(columnFamilyQuery, CQLTranslator.COLUMNS, queryBuilder.toString()); + queryBuilder = new StringBuilder(columnFamilyQuery); + } + return queryBuilder; + } + + private void createIndexUsingThrift(TableInfo tableInfo, CfDef cfDef) throws Exception + { + for (IndexInfo indexInfo : tableInfo.getColumnsToBeIndexed()) + { + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (new String(columnDef.getName(), Constants.ENCODING).equals(indexInfo.getColumnName())) + { + columnDef.setIndex_type(CassandraIndexHelper.getIndexType(indexInfo.getIndexType())); + } + } + } + cassandra_client.system_update_column_family(cfDef); + } + + /** + * Create secondary indexes on columns. + * + * @param tableInfo + */ + private void createIndexUsingCql(TableInfo tableInfo) throws Exception + { + StringBuilder indexQueryBuilder = new StringBuilder("create index $COLUMN_NAME on \""); + indexQueryBuilder.append(tableInfo.getTableName()); + indexQueryBuilder.append("\"(\"$COLUMN_NAME\")"); + for (IndexInfo indexInfo : tableInfo.getColumnsToBeIndexed()) + { + ColumnInfo columnInfo = new ColumnInfo(); + columnInfo.setColumnName(indexInfo.getColumnName()); + if(! tableInfo.getEmbeddedColumnMetadatas().isEmpty()) + { + List columnInfos = tableInfo.getEmbeddedColumnMetadatas().get(0).getColumns(); + if (columnInfos.contains(columnInfo)) + { + return; + } + } + String replacedWithindexName = StringUtils.replace(indexQueryBuilder.toString(), "$COLUMN_NAME", + indexInfo.getColumnName()); + try + { + cassandra_client.execute_cql3_query(ByteBuffer.wrap(replacedWithindexName.getBytes()), + Compression.NONE, ConsistencyLevel.ONE); + } + catch (InvalidRequestException ire) + { + if (ire.getWhy() != null && !ire.getWhy().equals("Index already exists") + && operation.equalsIgnoreCase(SchemaOperationType.update.name())) + { + log.error("Error occurred while creating indexes on column{} of table {}, , Caused by: .", + indexInfo.getColumnName(), tableInfo.getTableName(), ire); + throw new SchemaGenerationException("Error occurred while creating indexes on column " + + indexInfo.getColumnName() + " of table " + tableInfo.getTableName(), ire, "Cassandra", + databaseName); + } + } + } + } + + /** + * Drops table using cql3. + * + * @param tableInfo + */ + private void dropTableUsingCql(TableInfo tableInfo) throws Exception + { + CQLTranslator translator = new CQLTranslator(); + StringBuilder dropQuery = new StringBuilder("drop table "); + translator.ensureCase(dropQuery, tableInfo.getTableName()); + cassandra_client.execute_cql3_query(ByteBuffer.wrap(dropQuery.toString().getBytes()), Compression.NONE, + ConsistencyLevel.ONE); + } + + /** + * Adds column to table if not exists previously i.e. alter table. + * + * @param tableInfo + * @param translator + * @param column + * @throws TException + * @throws SchemaDisagreementException + * @throws TimedOutException + * @throws UnavailableException + * @throws InvalidRequestException + */ + private void addColumnToTable(TableInfo tableInfo, ColumnInfo column) throws Exception + { + CQLTranslator translator = new CQLTranslator(); + StringBuilder addColumnQuery = new StringBuilder("ALTER TABLE "); + translator.ensureCase(addColumnQuery, tableInfo.getTableName()); + addColumnQuery.append(" ADD "); + translator.ensureCase(addColumnQuery, column.getColumnName()); + addColumnQuery.append(" " + + translator.getCQLType(CassandraValidationClassMapper.getValidationClass(column.getType(), + isCql3Enabled(tableInfo)))); + try + { + cassandra_client.execute_cql3_query(ByteBuffer.wrap(addColumnQuery.toString().getBytes()), + Compression.NONE, ConsistencyLevel.ONE); + } + catch (InvalidRequestException ireforAddColumn) + { + StringBuilder ireforAddColumnbBuilder = new StringBuilder("Invalid column name "); + ireforAddColumnbBuilder.append(column.getColumnName() + " because it conflicts with an existing column"); + if (ireforAddColumn.getWhy() != null && ireforAddColumn.getWhy().equals(ireforAddColumnbBuilder.toString())) + { + alterColumnType(tableInfo, translator, column); + } + else + { + log.error("Error occurred while altering column type of table {}, Caused by: .", + tableInfo.getTableName(), ireforAddColumn); + throw new SchemaGenerationException("Error occurred while adding column into table " + + tableInfo.getTableName(), ireforAddColumn, "Cassandra", databaseName); + } + } + + } + + /** + * Alters column type of an existing column. + * + * @param tableInfo + * @param translator + * @param column + * @throws TException + * @throws SchemaDisagreementException + * @throws TimedOutException + * @throws UnavailableException + * @throws InvalidRequestException + */ + private void alterColumnType(TableInfo tableInfo, CQLTranslator translator, ColumnInfo column) throws Exception + { + StringBuilder alterColumnTypeQuery = new StringBuilder("ALTER TABLE "); + translator.ensureCase(alterColumnTypeQuery, tableInfo.getTableName()); + alterColumnTypeQuery.append(" ALTER "); + translator.ensureCase(alterColumnTypeQuery, column.getColumnName()); + alterColumnTypeQuery.append(" TYPE " + + translator.getCQLType(CassandraValidationClassMapper.getValidationClass(column.getType(), + isCql3Enabled(tableInfo)))); + cassandra_client.execute_cql3_query(ByteBuffer.wrap(alterColumnTypeQuery.toString().getBytes()), + Compression.NONE, ConsistencyLevel.ONE); + } + + /** + * On composite columns. + * + * @param translator + * the translator + * @param columns + * the columns + * @param queryBuilder + * the query builder + */ + private void onCompositeColumns(CQLTranslator translator, List compositeColumns, + StringBuilder queryBuilder, List columns) + { + for (ColumnInfo colInfo : compositeColumns) + { + if (columns == null || (columns != null && !columns.contains(colInfo))) + { + String dataType = CassandraValidationClassMapper.getValidationClass(colInfo.getType(), true); + String cqlType = translator.getCQLType(dataType); + translator.appendColumnName(queryBuilder, colInfo.getColumnName(), cqlType); + queryBuilder.append(" ,"); + } + } + } + + /** + * Generates schema for Collection columns + * @param translator + * @param collectionColumnInfos + * @param queryBuilder + */ + private void onCollectionColumns(CQLTranslator translator, List collectionColumnInfos, + StringBuilder queryBuilder) + { + for (CollectionColumnInfo cci : collectionColumnInfos) + { + String dataType = CassandraValidationClassMapper.getValidationClass(cci.getType(), true); + + //CQL Type of collection column + String collectionCqlType = translator.getCQLType(dataType); + + //Collection Column Name + String collectionColumnName = new String(cci.getCollectionColumnName()); + + //Generic Type list + StringBuilder genericTypesBuilder = null; + List> genericClasses = cci.getGenericClasses(); + if (!genericClasses.isEmpty()) + { + genericTypesBuilder = new StringBuilder(); + if (MapType.class.getSimpleName().equals(dataType) && genericClasses.size() == 2) + { + genericTypesBuilder.append("<"); + String keyDataType = CassandraValidationClassMapper.getValidationClass(genericClasses.get(0), true); + genericTypesBuilder.append(translator.getCQLType(keyDataType)); + genericTypesBuilder.append(","); + String valueDataType = CassandraValidationClassMapper.getValidationClass(genericClasses.get(1), true); + genericTypesBuilder.append(translator.getCQLType(valueDataType)); + genericTypesBuilder.append(">"); + } + else if ((ListType.class.getSimpleName().equals(dataType) + || SetType.class.getSimpleName().equals(dataType)) && genericClasses.size() == 1) + { + genericTypesBuilder.append("<"); + String valueDataType = CassandraValidationClassMapper.getValidationClass(genericClasses.get(0), true); + genericTypesBuilder.append(translator.getCQLType(valueDataType)); + genericTypesBuilder.append(">"); + } + else + { + throw new SchemaGenerationException("Incorrect collection field definition for " + + cci.getCollectionColumnName() + ". Genric Types must be defined correctly."); + } + } + + if(genericTypesBuilder != null) + { + collectionCqlType += genericTypesBuilder.toString(); + } + + translator.appendColumnName(queryBuilder, collectionColumnName, collectionCqlType); + queryBuilder.append(" ,"); + + } + } + + /** + * Creates the inverted index table. + * + * @param tableInfo + * the table info + * @throws InvalidRequestException + * the invalid request exception + * @throws SchemaDisagreementException + * the schema disagreement exception + * @throws TException + * the t exception + */ + private void createInvertedIndexTable(TableInfo tableInfo) throws InvalidRequestException, + SchemaDisagreementException, TException + { + CfDef cfDef = getInvertedIndexCF(tableInfo); + if (cfDef != null) + { + cassandra_client.system_add_column_family(cfDef); + } + } + + /** + * @param tableInfo + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private CfDef getInvertedIndexCF(TableInfo tableInfo) throws InvalidRequestException, SchemaDisagreementException, + TException + { + boolean indexTableRequired = CassandraPropertyReader.csmd.isInvertedIndexingEnabled(databaseName) + && !tableInfo.getEmbeddedColumnMetadatas().isEmpty(); + if (indexTableRequired) + { + CfDef cfDef = new CfDef(); + cfDef.setKeyspace(databaseName); + cfDef.setColumn_type("Super"); + cfDef.setName(tableInfo.getTableName() + Constants.INDEX_TABLE_SUFFIX); + cfDef.setKey_validation_class(UTF8Type.class.getSimpleName()); + return cfDef; + } + return null; + } + + /** + * Drop inverted index table. + * + * @param tableInfo + * the table info + */ + private void dropInvertedIndexTable(TableInfo tableInfo) + { + boolean indexTableRequired = CassandraPropertyReader.csmd.isInvertedIndexingEnabled(databaseName)/* ) */ + && !tableInfo.getEmbeddedColumnMetadatas().isEmpty(); + if (indexTableRequired) + { + try + { + cassandra_client.system_drop_column_family(tableInfo.getTableName() + Constants.INDEX_TABLE_SUFFIX); + } + catch (Exception ex) + { + if (log.isWarnEnabled()) + { + log.warn("Error while dropping inverted index table, Caused by: ", ex); + } + } + } + } + + /** + * check for Tables method check the existence of schema and table. + * + * @param tableInfos + * list of TableInfos and ksDef object of KsDef + * @param ksDef + * the ks def + * @throws TException + * @throws InvalidRequestException + */ + private void onValidateTables(List tableInfos, KsDef ksDef) throws Exception + { + cassandra_client.set_keyspace(ksDef.getName()); + for (TableInfo tableInfo : tableInfos) + { + onValidateTable(ksDef, tableInfo); + } + } + + private void onValidateTable(KsDef ksDef, TableInfo tableInfo) throws Exception + { + boolean tablefound = false; + for (CfDef cfDef : ksDef.getCf_defs()) + { + if (cfDef.getName().equals(tableInfo.getTableName()) + && (cfDef.getColumn_type().equals(ColumnFamilyType.getInstanceOf(tableInfo.getType()).name()))) + { + if (cfDef.getColumn_type().equals(ColumnFamilyType.Standard.name())) + { + for (ColumnInfo columnInfo : tableInfo.getColumnMetadatas()) + { + onValidateColumn(tableInfo, cfDef, columnInfo); + } + tablefound = true; + break; + } + else if (cfDef.getColumn_type().equals(ColumnFamilyType.Super.name())) + { + tablefound = true; + } + } + } + if (!tablefound) + { + throw new SchemaGenerationException("Column family " + tableInfo.getTableName() + + " does not exist in keyspace " + databaseName + "", "Cassandra", databaseName, + tableInfo.getTableName()); + } + } + + private void onValidateColumn(TableInfo tableInfo, CfDef cfDef, ColumnInfo columnInfo) throws Exception + { + boolean columnfound = false; + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (isMetadataSame(columnDef, columnInfo, isCql3Enabled(tableInfo))) + { + columnfound = true; + break; + } + } + if (!columnfound) + { + throw new SchemaGenerationException("Column " + columnInfo.getColumnName() + + " does not exist in column family " + tableInfo.getTableName() + "", "Cassandra", databaseName, + tableInfo.getTableName()); + } + } + + /** + * is metadata same method returns true if ColumnDef and columnInfo have + * same metadata. + * + * @param columnDef + * the column def + * @param columnInfo + * the column info + * @return true, if is metadata same + * @throws UnsupportedEncodingException + * the unsupported encoding exception + */ + private boolean isMetadataSame(ColumnDef columnDef, ColumnInfo columnInfo, boolean isCql3Enabled) throws Exception + { + return isIndexPresent(columnInfo, columnDef, isCql3Enabled); + } + + /** + * + * @param ksDef + * @param tableInfo + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + * @throws UnsupportedEncodingException + */ + private void updateTable(KsDef ksDef, TableInfo tableInfo) throws Exception + { + for (CfDef cfDef : ksDef.getCf_defs()) + { + if (cfDef.getName().equals(tableInfo.getTableName()) + && cfDef.getColumn_type().equals(ColumnFamilyType.getInstanceOf(tableInfo.getType()).name())) + { + boolean toUpdate = false; + if (cfDef.getColumn_type().equals(STANDARDCOLUMNFAMILY)) + { + for (ColumnInfo columnInfo : tableInfo.getColumnMetadatas()) + { + toUpdate = isCfDefUpdated(columnInfo, cfDef, isCql3Enabled(tableInfo), tableInfo) ? true + : toUpdate; + } + } + if (toUpdate) + { + cassandra_client.system_update_column_family(cfDef); + createIndexUsingThrift(tableInfo, cfDef); + } + break; + } + } + } + + private boolean isCfDefUpdated(ColumnInfo columnInfo, CfDef cfDef, boolean isCql3Enabled, TableInfo tableInfo) + throws Exception + { + boolean columnPresent = false; + boolean isUpdated = false; + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (isColumnPresent(columnInfo, columnDef, isCql3Enabled)) + { + if (!isValidationClassSame(columnInfo, columnDef, isCql3Enabled)) + { + columnDef.setValidation_class(CassandraValidationClassMapper.getValidationClass( + columnInfo.getType(), isCql3Enabled)); + columnDef.setIndex_typeIsSet(false); + columnDef.setIndex_nameIsSet(false); + isUpdated = true; + } + columnPresent = true; + break; + } + } + if (!columnPresent) + { + cfDef.addToColumn_metadata(getColumnMetadata(columnInfo, tableInfo)); + isUpdated = true; + } + return isUpdated; + } + + /** + * isInedexesPresent method return whether indexes present or not on + * particular column. + * + * @param columnInfo + * the column info + * @param cfDef + * the cf def + * @return true, if is indexes present + * @throws UnsupportedEncodingException + */ + private boolean isColumnPresent(ColumnInfo columnInfo, ColumnDef columnDef, boolean isCql3Enabled) throws Exception + { + return (new String(columnDef.getName(), Constants.ENCODING).equals(columnInfo.getColumnName())); + } + + /** + * isInedexesPresent method return whether indexes present or not on + * particular column. + * + * @param columnInfo + * the column info + * @param cfDef + * the cf def + * @return true, if is indexes present + * @throws UnsupportedEncodingException + */ + private boolean isValidationClassSame(ColumnInfo columnInfo, ColumnDef columnDef, boolean isCql3Enabled) + throws Exception + { + return (isColumnPresent(columnInfo, columnDef, isCql3Enabled) && columnDef.getValidation_class().endsWith( + CassandraValidationClassMapper.getValidationClass(columnInfo.getType(), isCql3Enabled))); + } + + /** + * isInedexesPresent method return whether indexes present or not on + * particular column. + * + * @param columnInfo + * the column info + * @param cfDef + * the cf def + * @return true, if is indexes present + * @throws UnsupportedEncodingException + */ + private boolean isIndexPresent(ColumnInfo columnInfo, ColumnDef columnDef, boolean isCql3Enabled) throws Exception + { + return (isValidationClassSame(columnInfo, columnDef, isCql3Enabled) && (columnDef.isSetIndex_type() == columnInfo + .isIndexable() || (columnDef.isSetIndex_type()))); + } + + /** + * getColumnMetadata use for getting column metadata for specific + * columnInfo. + * + * @param columnInfo + * the column info + * @return the column metadata + */ + private ColumnDef getColumnMetadata(ColumnInfo columnInfo, TableInfo tableInfo) + { + ColumnDef columnDef = new ColumnDef(); + columnDef.setName(columnInfo.getColumnName().getBytes()); + columnDef.setValidation_class(CassandraValidationClassMapper.getValidationClass(columnInfo.getType(), + isCql3Enabled(tableInfo))); + + if (columnInfo.isIndexable()) + { + IndexInfo indexInfo = tableInfo.getColumnToBeIndexed(columnInfo.getColumnName()); + columnDef.setIndex_type(CassandraIndexHelper.getIndexType(indexInfo.getIndexType())); + } + return columnDef; + } + + /** + * Sets the properties. + * + * @param ksDef + * the ks def + * @param strategy_options + * the strategy_options + */ + private void setProperties(KsDef ksDef, Map strategy_options) + { + Schema schema = CassandraPropertyReader.csmd.getSchema(databaseName); + if (schema != null && schema.getName() != null && schema.getName().equalsIgnoreCase(databaseName) + && schema.getSchemaProperties() != null) + { + setKeyspaceProperties(ksDef, schema.getSchemaProperties(), strategy_options, schema.getDataCenters()); + } + else + { + setDefaultReplicationFactor(strategy_options); + } + } + + /** + * @param strategy_options + */ + private void setDefaultReplicationFactor(Map strategy_options) + { + strategy_options.put("replication_factor", CassandraConstants.DEFAULT_REPLICATION_FACTOR); + } + + /** + * Sets the keyspace properties. + * + * @param ksDef + * the ks def + * @param schemaProperties + * the schema properties + * @param strategyOptions + * the strategy options + * @param dcs + * the dcs + */ + private void setKeyspaceProperties(KsDef ksDef, Properties schemaProperties, Map strategyOptions, + List dcs) + { + String placementStrategy = schemaProperties.getProperty(CassandraConstants.PLACEMENT_STRATEGY, + SimpleStrategy.class.getSimpleName()); + if (placementStrategy.equalsIgnoreCase(SimpleStrategy.class.getSimpleName()) + || placementStrategy.equalsIgnoreCase(SimpleStrategy.class.getName())) + { + String replicationFactor = schemaProperties.getProperty(CassandraConstants.REPLICATION_FACTOR, + CassandraConstants.DEFAULT_REPLICATION_FACTOR); + strategyOptions.put("replication_factor", replicationFactor); + } + else if (placementStrategy.equalsIgnoreCase(NetworkTopologyStrategy.class.getSimpleName()) + || placementStrategy.equalsIgnoreCase(NetworkTopologyStrategy.class.getName())) + { + if (dcs != null && !dcs.isEmpty()) + { + for (DataCenter dc : dcs) + { + strategyOptions.put(dc.getName(), dc.getValue()); + } + } + } + else + { + strategyOptions.put("replication_factor", CassandraConstants.DEFAULT_REPLICATION_FACTOR); + } + + ksDef.setStrategy_class(placementStrategy); + ksDef.setDurable_writes(Boolean.parseBoolean(schemaProperties.getProperty(CassandraConstants.DURABLE_WRITES))); + } + + /** + * Gets the column family properties. + * + * @param tableInfo + * the table info + * @return the column family properties + */ + private Properties getColumnFamilyProperties(TableInfo tableInfo) + { + if (tables != null) + { + for (Table table : tables) + { + if (table != null && table.getName() != null + && table.getName().equalsIgnoreCase(tableInfo.getTableName())) + { + return table.getProperties(); + } + } + } + return null; + } + + /** + * Enum ColumnFamilyType for type of column family in cassandra ie Super or + * Standard. + * + */ + private enum ColumnFamilyType + { + + /** The Standard. */ + Standard, + /** The Super. */ + Super; + + /** + * Gets the instance of. + * + * @param type + * the type + * @return the instance of + */ + private static ColumnFamilyType getInstanceOf(String type) + { + if (type.equals(Type.COLUMN_FAMILY.name())) + { + return ColumnFamilyType.Standard; + } + else + { + return ColumnFamilyType.Super; + } + } + } + + /** + * validates entity for CounterColumnType. + * + * @param clazz + * the clazz + * @return true, if successful + */ + @Override + public boolean validateEntity(Class clazz) + { + EntityValidatorAgainstCounterColumn entityValidatorAgainstSchema = new EntityValidatorAgainstCounterColumn(); + return entityValidatorAgainstSchema.validateEntity(clazz); + } + + /** + * Sets the column family properties. + * + * @param cfDef + * the cf def + * @param cFProperties + * the c f properties + */ + private void setColumnFamilyProperties(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + if ((cfDef != null && cFProperties != null) || (builder != null && cFProperties != null)) + { + if (builder != null) + { + builder.append(CQLTranslator.WITH_CLAUSE); + } + onSetKeyValidation(cfDef, cFProperties, builder); + + onSetCompactionStrategy(cfDef, cFProperties, builder); + + onSetComparatorType(cfDef, cFProperties, builder); + + onSetSubComparator(cfDef, cFProperties, builder); + + onSetReplicateOnWrite(cfDef, cFProperties, builder); + + onSetCompactionThreshold(cfDef, cFProperties, builder); + + onSetComment(cfDef, cFProperties, builder); + + onSetTableId(cfDef, cFProperties, builder); + + onSetGcGrace(cfDef, cFProperties, builder); + + onSetCaching(cfDef, cFProperties, builder); + + onSetBloomFilter(cfDef, cFProperties, builder); + + onSetRepairChance(cfDef, cFProperties, builder); + + onSetReadRepairChance(cfDef, cFProperties, builder); + + // Strip last AND clause. + if (builder != null && StringUtils.contains(builder.toString(), CQLTranslator.AND_CLAUSE)) + { + builder.delete(builder.lastIndexOf(CQLTranslator.AND_CLAUSE), builder.length()); + // builder.deleteCharAt(builder.length() - 2); + } + } + } + + private void onSetReadRepairChance(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String dclocalReadRepairChance = cFProperties.getProperty(CassandraConstants.DCLOCAL_READ_REPAIR_CHANCE); + if (dclocalReadRepairChance != null) + { + try + { + if (builder != null) + { + appendPropertyToBuilder(builder, dclocalReadRepairChance, + CassandraConstants.DCLOCAL_READ_REPAIR_CHANCE); + + } + else + { + cfDef.setDclocal_read_repair_chance(Double.parseDouble(dclocalReadRepairChance)); + } + } + catch (NumberFormatException nfe) + { + log.error("READ_REPAIR_CHANCE should be double type, Caused by: .", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetRepairChance(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String readRepairChance = cFProperties.getProperty(CassandraConstants.READ_REPAIR_CHANCE); + if (readRepairChance != null) + { + try + { + if (builder != null) + { + appendPropertyToBuilder(builder, readRepairChance, CassandraConstants.READ_REPAIR_CHANCE); + } + else + { + cfDef.setRead_repair_chance(Double.parseDouble(readRepairChance)); + } + } + catch (NumberFormatException nfe) + { + log.error("READ_REPAIR_CHANCE should be double type, Caused by: .", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetBloomFilter(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String bloomFilterFpChance = cFProperties.getProperty(CassandraConstants.BLOOM_FILTER_FP_CHANCE); + if (bloomFilterFpChance != null) + { + try + { + if (builder != null) + { + appendPropertyToBuilder(builder, bloomFilterFpChance, CassandraConstants.BLOOM_FILTER_FP_CHANCE); + } + else + { + cfDef.setBloom_filter_fp_chance(Double.parseDouble(bloomFilterFpChance)); + } + } + catch (NumberFormatException nfe) + { + log.error("BLOOM_FILTER_FP_CHANCE should be double type, Caused by: .", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetCaching(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String caching = cFProperties.getProperty(CassandraConstants.CACHING); + if (caching != null) + { + if (builder != null) + { + appendPropertyToBuilder(builder, caching, CassandraConstants.CACHING); + } + else + { + cfDef.setCaching(caching); + } + } + } + + private void onSetGcGrace(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String gcGraceSeconds = cFProperties.getProperty(CassandraConstants.GC_GRACE_SECONDS); + if (gcGraceSeconds != null) + { + try + { + if (builder != null) + { + appendPropertyToBuilder(builder, gcGraceSeconds, CassandraConstants.GC_GRACE_SECONDS); + } + else + { + cfDef.setGc_grace_seconds(Integer.parseInt(gcGraceSeconds)); + } + } + catch (NumberFormatException nfe) + { + log.error("GC_GRACE_SECONDS should be numeric type, Caused by: .", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetTableId(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String id = cFProperties.getProperty(CassandraConstants.ID); + if (id != null) + { + try + { + if (builder != null) + { + // TODO::::not available with composite key? + } + else + { + cfDef.setId(Integer.parseInt(id)); + } + } + catch (NumberFormatException nfe) + { + log.error("Id should be numeric type, Caused by: ", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetComment(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String comment = cFProperties.getProperty(CassandraConstants.COMMENT); + if (comment != null) + { + if (builder != null) + { + String comment_Str = CQLTranslator.getKeyword(CassandraConstants.COMMENT); + builder.append(comment_Str); + builder.append(CQLTranslator.EQ_CLAUSE); + builder.append(CQLTranslator.QUOTE_STR); + builder.append(comment); + builder.append(CQLTranslator.QUOTE_STR); + builder.append(CQLTranslator.AND_CLAUSE); + + } + else + { + cfDef.setComment(comment); + } + } + } + + private void onSetReplicateOnWrite(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String replicateOnWrite = cFProperties.getProperty(CassandraConstants.REPLICATE_ON_WRITE); + if (builder != null) + { + appendPropertyToBuilder(builder, replicateOnWrite, CassandraConstants.REPLICATE_ON_WRITE); + } + else + { + cfDef.setReplicate_on_write(Boolean.parseBoolean(replicateOnWrite)); + } + } + + private void onSetCompactionThreshold(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String maxCompactionThreshold = cFProperties.getProperty(CassandraConstants.MAX_COMPACTION_THRESHOLD); + if (maxCompactionThreshold != null) + { + try + { + if (builder != null) + { + // Somehow these are not working for cassandra 1.1 + // though they claim it should work. + // appendPropertyToBuilder(builder, + // maxCompactionThreshold, + // CassandraConstants.MAX_COMPACTION_THRESHOLD); + } + else + { + cfDef.setMax_compaction_threshold(Integer.parseInt(maxCompactionThreshold)); + } + } + catch (NumberFormatException nfe) + { + log.error("Max_Compaction_Threshold should be numeric type, Caused by: .", nfe); + throw new SchemaGenerationException(nfe); + } + } + String minCompactionThreshold = cFProperties.getProperty(CassandraConstants.MIN_COMPACTION_THRESHOLD); + if (minCompactionThreshold != null) + { + try + { + if (builder != null) + { + // Somehow these are not working for cassandra 1.1 + // though they claim it should work. + // appendPropertyToBuilder(builder, + // minCompactionThreshold, + // CassandraConstants.MIN_COMPACTION_THRESHOLD); + } + else + { + cfDef.setMin_compaction_threshold(Integer.parseInt(minCompactionThreshold)); + } + } + catch (NumberFormatException nfe) + { + log.error("Min_Compaction_Threshold should be numeric type, Caused by: . ", nfe); + throw new SchemaGenerationException(nfe); + } + } + } + + private void onSetSubComparator(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String subComparatorType = cFProperties.getProperty(CassandraConstants.SUBCOMPARATOR_TYPE); + if (subComparatorType != null && ColumnFamilyType.valueOf(cfDef.getColumn_type()) == ColumnFamilyType.Super) + { + if (builder != null) + { + // super column are not supported for composite key as of + // now, leaving blank place holder.. + } + else + { + cfDef.setSubcomparator_type(subComparatorType); + } + } + } + + private void onSetComparatorType(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String comparatorType = cFProperties.getProperty(CassandraConstants.COMPARATOR_TYPE); + if (comparatorType != null) + { + if (builder != null) + { + // TODO:::nothing available. + } + else + { + cfDef.setComparator_type(comparatorType); + } + } + } + + private void onSetCompactionStrategy(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String compactionStrategy = cFProperties.getProperty(CassandraConstants.COMPACTION_STRATEGY); + if (compactionStrategy != null) + { + if (builder != null) + { + String strategy_class = CQLTranslator.getKeyword(CassandraConstants.COMPACTION_STRATEGY); + builder.append(strategy_class); + builder.append(CQLTranslator.EQ_CLAUSE); + builder.append(CQLTranslator.QUOTE_STR); + builder.append(compactionStrategy); + builder.append(CQLTranslator.QUOTE_STR); + builder.append(CQLTranslator.AND_CLAUSE); + } + else + { + cfDef.setCompaction_strategy(compactionStrategy); + } + } + } + + private void onSetKeyValidation(CfDef cfDef, Properties cFProperties, StringBuilder builder) + { + String keyValidationClass = cFProperties.getProperty(CassandraConstants.KEY_VALIDATION_CLASS); + if (keyValidationClass != null) + { + if (builder != null) + { + // nothing available. + } + else + { + cfDef.setKey_validation_class(keyValidationClass); + } + } + } + + /** + * + * @param tableInfo + * @return + */ + private boolean isCql3Enabled(TableInfo tableInfo) + { + return containsCompositeKey(tableInfo) + || ((cql_version != null && cql_version.equals(CassandraConstants.CQL_VERSION_3_0)) && !tableInfo + .getType().equals(Type.SUPER_COLUMN_FAMILY.name())); + } + + /** + * @param builder + * @param replicateOnWrite + * @param keyword + */ + private void appendPropertyToBuilder(StringBuilder builder, String replicateOnWrite, String keyword) + { + String replicateOn_Write = CQLTranslator.getKeyword(keyword); + builder.append(replicateOn_Write); + builder.append(CQLTranslator.EQ_CLAUSE); + builder.append(replicateOnWrite); + builder.append(CQLTranslator.AND_CLAUSE); + } + + /** + * + * @param tableInfo + */ + private void validateCompoundKey(TableInfo tableInfo) + { + if (tableInfo.getType() != null && tableInfo.getType().equals(Type.SUPER_COLUMN_FAMILY.name())) + { + throw new SchemaGenerationException( + "Composite/Compound columns are not yet supported over Super column family by Cassandra", + "cassandra", databaseName); + } + } + + /** + * MetaDataHandler responsible for creating column family matadata for + * tableInfos. + * + * @author Kuldeep.Mishra + * + */ + private class MetaDataHandler + { + /** + * get Table metadata method returns the metadata of table for given + * tableInfo. + * + * @param tableInfo + * the table info + * @return the table metadata + */ + /** + * @param tableInfo + * @return CfDef object + */ + private CfDef getTableMetadata(TableInfo tableInfo) + { + CfDef cfDef = new CfDef(); + cfDef.setKeyspace(databaseName); + cfDef.setName(tableInfo.getTableName()); + cfDef.setKey_validation_class(CassandraValidationClassMapper.getValidationClass(tableInfo.getTableIdType(), + isCql3Enabled(tableInfo))); + + Schema schema = CassandraPropertyReader.csmd.getSchema(databaseName); + tables = schema != null ? schema.getTables() : null; + + Properties cFProperties = getColumnFamilyProperties(tableInfo); + String defaultValidationClass = null; + if (tableInfo.getType() != null && tableInfo.getType().equals(Type.SUPER_COLUMN_FAMILY.name())) + { + getSuperColumnFamilyMetadata(tableInfo, cfDef, defaultValidationClass); + } + else if (tableInfo.getType() != null) + { + getColumnFamilyMetadata(tableInfo, cfDef, cFProperties); + } + setColumnFamilyProperties(cfDef, cFProperties, null); + return cfDef; + } + + /** + * + * @param tableInfo + * @param cfDef + * @param defaultValidationClass + */ + private void getSuperColumnFamilyMetadata(TableInfo tableInfo, CfDef cfDef, String defaultValidationClass) + { + if (isCounterColumnType(tableInfo, defaultValidationClass)) + { + cfDef.setDefault_validation_class(CounterColumnType.class.getSimpleName()); + } + cfDef.setColumn_type("Super"); + cfDef.setComparator_type(UTF8Type.class.getSimpleName()); + cfDef.setSubcomparator_type(UTF8Type.class.getSimpleName()); + } + + /** + * + * @param tableInfo + * @param cfDef + * @param cFProperties + */ + private void getColumnFamilyMetadata(TableInfo tableInfo, CfDef cfDef, Properties cFProperties) + { + String defaultValidationClass; + defaultValidationClass = cFProperties != null ? cFProperties + .getProperty(CassandraConstants.DEFAULT_VALIDATION_CLASS) : null; + cfDef.setColumn_type(STANDARDCOLUMNFAMILY); + cfDef.setComparator_type(UTF8Type.class.getSimpleName()); + if (isCounterColumnType(tableInfo, defaultValidationClass)) + { + getCounterColumnFamilyMetadata(tableInfo, cfDef); + } + else + { + List columnDefs = new ArrayList(); + List columnInfos = tableInfo.getColumnMetadatas(); + if (columnInfos != null) + { + for (ColumnInfo columnInfo : columnInfos) + { + ColumnDef columnDef = new ColumnDef(); + if (columnInfo.isIndexable()) + { + IndexInfo indexInfo = tableInfo.getColumnToBeIndexed(columnInfo.getColumnName()); + columnDef.setIndex_type(CassandraIndexHelper.getIndexType(indexInfo.getIndexType())); + } + columnDef.setName(columnInfo.getColumnName().getBytes()); + columnDef.setValidation_class(CassandraValidationClassMapper.getValidationClass( + columnInfo.getType(), isCql3Enabled(tableInfo))); + columnDefs.add(columnDef); + } + } + cfDef.setColumn_metadata(columnDefs); + } + } + + /** + * + * @param tableInfo + * @param cfDef + */ + private void getCounterColumnFamilyMetadata(TableInfo tableInfo, CfDef cfDef) + { + cfDef.setDefault_validation_class(CounterColumnType.class.getSimpleName()); + List counterColumnDefs = new ArrayList(); + List columnInfos = tableInfo.getColumnMetadatas(); + if (columnInfos != null) + { + for (ColumnInfo columnInfo : columnInfos) + { + ColumnDef columnDef = new ColumnDef(); + if (columnInfo.isIndexable()) + { + IndexInfo indexInfo = tableInfo.getColumnToBeIndexed(columnInfo.getColumnName()); + columnDef.setIndex_type(CassandraIndexHelper.getIndexType(indexInfo.getIndexType())); + } + columnDef.setName(columnInfo.getColumnName().getBytes()); + columnDef.setValidation_class(CounterColumnType.class.getName()); + counterColumnDefs.add(columnDef); + } + } + cfDef.setColumn_metadata(counterColumnDefs); + } + + /** + * Checks if is counter column type. + * + * @param tableInfo + * the table info + * @param defaultValidationClass + * the default validation class + * @return true, if is counter column type + */ + private boolean isCounterColumnType(TableInfo tableInfo, String defaultValidationClass) + { + return (csmd != null && csmd.isCounterColumn(databaseName, tableInfo.getTableName())) + || (defaultValidationClass != null + && (defaultValidationClass.equalsIgnoreCase(CounterColumnType.class.getSimpleName()) || defaultValidationClass + .equalsIgnoreCase(CounterColumnType.class.getName())) || (tableInfo.getType() + .equals(CounterColumnType.class.getSimpleName()))); + } + } + + /** + * EntityValidatorAgainstCounterColumn class responsible for validating + * classes against counter column family. + * + * @author Kuldeep.Mishra + * + */ + private class EntityValidatorAgainstCounterColumn + { + /** + * validates entity for CounterColumnType. + * + * @param clazz + * the clazz + * @return true, if successful + */ + private boolean validateEntity(Class clazz) + { + boolean isvalid = false; + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(clazz); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + String tableName = metadata.getTableName(); + if (csmd.isCounterColumn(metadata.getSchema(), tableName)) + { + metadata.setCounterColumnType(true); + Map embeddables = metaModel.getEmbeddables(clazz); + if (!embeddables.isEmpty()) + { + isvalid = validateEmbeddedColumns(metadata, embeddables.values()) ? true : false; + } + else + { + EntityType entity = metaModel.entity(clazz); + isvalid = validateColumns(metadata, entity.getAttributes()) ? true : false; + } + isvalid = isvalid && validateRelations(metadata) ? true : false; + } + else + { + return true; + } + return isvalid; + } + + /** + * validates entity relations if any present. + * + * @param metadata + * the metadata + * @return true, if successful + */ + private boolean validateRelations(EntityMetadata metadata) + { + boolean isValid = true; + for (Relation relation : metadata.getRelations()) + { + EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation + .getTargetEntity()); + if (((relation.getType().equals(ForeignKey.ONE_TO_ONE) && !relation.isJoinedByPrimaryKey()) || relation + .getType().equals(ForeignKey.MANY_TO_MANY)) && relation.getMappedBy() == null) + { + // validate Id column of target entity + validateColumn(targetEntityMetadata.getIdAttribute().getJavaType()); + } + else if (relation.getType().equals(ForeignKey.ONE_TO_MANY) && relation.getMappedBy() == null) + { + // if target entity is also counter column the validate + // source + // IdColumn + String targetTableName = targetEntityMetadata.getTableName(); + if (csmd.isCounterColumn(targetEntityMetadata.getSchema(), targetTableName)) + { + isValid = validateColumn(metadata.getIdAttribute().getJavaType()) ? true : false; + } + } + } + return isValid; + } + + /** + * validate embedded column . + * + * @param metadata + * + * @param embeddedColumns + * the embedded columns + * @return true, if successful + */ + private boolean validateEmbeddedColumns(EntityMetadata metadata, Collection embeddedColumns) + { + boolean isValid = false; + Iterator iter = embeddedColumns.iterator(); + while (iter.hasNext()) + { + isValid = validateColumns(metadata, iter.next().getAttributes()) ? true : false; + } + return isValid; + } + + /** + * validate columns. + * + * @param metadata + * + * @param attributes + * the attributes + * @return true, if successful + */ + private boolean validateColumns(EntityMetadata metadata, Set attributes) + { + boolean isValid = true; + for (Attribute column : attributes) + { + if (!metadata.getIdAttribute().equals(column) && !validateColumn(column.getJavaType())) + { + isValid = false; + break; + } + } + return isValid; + } + + /** + * validate a single column. + * + * @param clazz + * the clazz + * @return true, if successful + */ + private boolean validateColumn(Class clazz) + { + boolean isValid = true; + if (!(clazz.equals(Integer.class) || clazz.equals(int.class) || clazz.equals(Long.class) || clazz + .equals(long.class))) + { + log.warn( + "Default valdation class :{}, For counter column type, fields of Entity should be either long type or integer type.", + CounterColumnType.class.getSimpleName()); + return isValid = false; + } + return isValid; + } + } +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraValidationClassMapper.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraValidationClassMapper.java new file mode 100644 index 000000000..5c7f8ac13 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/schemamanager/CassandraValidationClassMapper.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.schemamanager; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.cassandra.db.marshal.AsciiType; +import org.apache.cassandra.db.marshal.BooleanType; +import org.apache.cassandra.db.marshal.BytesType; +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.db.marshal.DateType; +import org.apache.cassandra.db.marshal.DecimalType; +import org.apache.cassandra.db.marshal.DoubleType; +import org.apache.cassandra.db.marshal.FloatType; +import org.apache.cassandra.db.marshal.Int32Type; +import org.apache.cassandra.db.marshal.IntegerType; +import org.apache.cassandra.db.marshal.ListType; +import org.apache.cassandra.db.marshal.LongType; +import org.apache.cassandra.db.marshal.SetType; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.db.marshal.UUIDType; +import org.apache.cassandra.locator.NetworkTopologyStrategy; +import org.apache.cassandra.locator.SimpleStrategy; +import org.codehaus.jackson.map.type.MapType; + +/** + * The Class CassandraValidationClassMapper holds the map of validation + * class(e.g. wrapper for default_validation_class property) mapper. + * + * @author Kuldeep.kumar + */ +public final class CassandraValidationClassMapper +{ + + /** The Constant validationClassMapper. */ + private final static HashMap, Class> validationClassMapper = new HashMap, Class>(); + + private final static List replication_strategies = new ArrayList(); + + private static List validatorsAndComparators = new ArrayList(); + static + { + // adding all possible strategies classes into list. + replication_strategies.add(SimpleStrategy.class.getName()); + replication_strategies.add(NetworkTopologyStrategy.class.getName()); + + // adding all possible validator and comparators into list. + validatorsAndComparators.add(BytesType.class.getSimpleName()); + validatorsAndComparators.add(AsciiType.class.getSimpleName()); + validatorsAndComparators.add(UTF8Type.class.getSimpleName()); + validatorsAndComparators.add(Int32Type.class.getSimpleName()); + validatorsAndComparators.add(IntegerType.class.getSimpleName()); + validatorsAndComparators.add(LongType.class.getSimpleName()); + validatorsAndComparators.add(UUIDType.class.getSimpleName()); + validatorsAndComparators.add(DateType.class.getSimpleName()); + validatorsAndComparators.add(BooleanType.class.getSimpleName()); + validatorsAndComparators.add(FloatType.class.getSimpleName()); + validatorsAndComparators.add(DoubleType.class.getSimpleName()); + validatorsAndComparators.add(DecimalType.class.getSimpleName()); + validatorsAndComparators.add(CounterColumnType.class.getSimpleName()); + + // putting possible combination into map. + validationClassMapper.put(java.lang.String.class, UTF8Type.class); + validationClassMapper.put(Character.class, UTF8Type.class); + validationClassMapper.put(char.class, UTF8Type.class); + + validationClassMapper.put(java.sql.Time.class, DateType.class); + validationClassMapper.put(java.lang.Integer.class, IntegerType.class); + validationClassMapper.put(int.class, IntegerType.class); + validationClassMapper.put(java.sql.Timestamp.class, DateType.class); + validationClassMapper.put(Short.class, IntegerType.class); + validationClassMapper.put(short.class, IntegerType.class); + validationClassMapper.put(java.math.BigDecimal.class, DecimalType.class); + validationClassMapper.put(java.sql.Date.class, DateType.class); + validationClassMapper.put(java.util.Date.class, DateType.class); + validationClassMapper.put(java.math.BigInteger.class, IntegerType.class); + + validationClassMapper.put(java.lang.Double.class, DoubleType.class); + validationClassMapper.put(double.class, DoubleType.class); + + validationClassMapper.put(boolean.class, BooleanType.class); + validationClassMapper.put(Boolean.class, BooleanType.class); + + validationClassMapper.put(java.lang.Long.class, LongType.class); + validationClassMapper.put(long.class, LongType.class); + + validationClassMapper.put(Byte.class, BytesType.class); + validationClassMapper.put(byte.class, BytesType.class); + + validationClassMapper.put(Float.class, FloatType.class); + validationClassMapper.put(float.class, FloatType.class); + + validationClassMapper.put(UUID.class, UUIDType.class); + + validationClassMapper.put(Calendar.class, DateType.class); + + validationClassMapper.put(List.class, ListType.class); + validationClassMapper.put(Set.class, SetType.class); + validationClassMapper.put(Map.class, MapType.class); + } + + /** + * Gets the validation class. + * + * @param dataType + * the data type + * @return the validation class + */ + public static String getValidationClass(Class dataType, boolean isCql3Enabled) + { + resetMapperForCQL3(isCql3Enabled); + Class validation_class; + validation_class = validationClassMapper.get(dataType); + if (!(validation_class != null)) + { + validation_class = BytesType.class; + } + resetMapperForThrift(isCql3Enabled); + return validation_class.getSimpleName(); + } + + public static Class getValidationClassInstance(Class dataType, boolean isCql3Enabled) + { + resetMapperForCQL3(isCql3Enabled); + Class validation_class; + validation_class = validationClassMapper.get(dataType); + if (!(validation_class != null)) + { + validation_class = BytesType.class; + } + resetMapperForThrift(isCql3Enabled); + return validation_class; + } + + public static List getReplicationStrategies() + { + return replication_strategies; + } + + /** + * @return the validatorsAndComparators + */ + public static List getValidatorsAndComparators() + { + return validatorsAndComparators; + } + + private static void resetMapperForCQL3(boolean isCql3Enabled) + { + if (isCql3Enabled) + { + validationClassMapper.put(java.lang.Integer.class, Int32Type.class); + validationClassMapper.put(int.class, Int32Type.class); + validationClassMapper.put(short.class, Int32Type.class); + validationClassMapper.put(Short.class, Int32Type.class); + validationClassMapper.put(Byte.class, Int32Type.class); + validationClassMapper.put(byte.class, Int32Type.class); + } + } + + private static void resetMapperForThrift(boolean isCql3Enabled) + { + if (isCql3Enabled) + { + validationClassMapper.put(java.lang.Integer.class, Int32Type.class); + validationClassMapper.put(int.class, IntegerType.class); + validationClassMapper.put(short.class, IntegerType.class); + validationClassMapper.put(Short.class, IntegerType.class); + validationClassMapper.put(Byte.class, BytesType.class); + validationClassMapper.put(byte.class, BytesType.class); + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHost.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHost.java new file mode 100644 index 000000000..c8f9f66df --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHost.java @@ -0,0 +1,343 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.service; + +import net.dataforte.cassandra.pool.HostFailoverPolicy; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.impetus.kundera.service.Host; + +/** + * Cassandra Host configuration. + * + * @author Kuldeep.Mishra + * + */ +public class CassandraHost implements Host +{ + + public static final int DEFAULT_PORT = 9160; + + public static final int DEFAULT_SHOCKET_TIMEOUT = 120000; + + public static final int DEFAULT_MAX_ACTIVE = 30; + + // Cap on the number of "idle" instances in the pool. + public static final int DEFAULT_MAX_IDLE = 10; + + // Minimum number of idle objects to maintain in each of the nodes. + public static final int DEFAULT_MIN_IDLE = 5; + + // Cap on the total number of instances from all nodes combined. + public static final int DEFAULT_MAX_TOTAL = 50; + + private int maxActive; + + // Cap on the number of "idle" instances in the pool. + private int maxIdle; + + // Minimum number of idle objects to maintain in each of the nodes. + private int minIdle; + + // Cap on the total number of instances from all nodes combined. + private int maxTotal; + + private String host; + + private int port; + + private int initialSize; + + private boolean testOnBorrow; + + private boolean testOnConnect; + + private boolean testOnReturn; + + private boolean testWhileIdle; + + private int socketTimeOut; + + private HostFailoverPolicy hostFailoverPolicy; + + private boolean retryHost; + + private String userName; + + private String password; + + private int maxWait; + + public CassandraHost(String host) + { + this.host = host; + this.port = DEFAULT_PORT; + } + + public CassandraHost(String host, int port) + { + this.host = host; + this.port = port; + } + + @Override + public String getHost() + { + return host; + } + + @Override + public int getPort() + { + return port; + } + + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof CassandraHost)) + { + return false; + } + CassandraHost other = (CassandraHost) obj; + return other.host.equals(this.host) && other.port == this.port; + } + + @Override + public int hashCode() + { + StringBuilder builder = new StringBuilder(host); + builder.append(port); + return HashCodeBuilder.reflectionHashCode(builder); + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(host); + builder.append(":"); + builder.append(port); + return builder.toString(); + } + + public void setInitialSize(int initialSize) + { + this.initialSize = initialSize; + } + + public void setTestOnBorrow(boolean testOnBorrow) + { + this.testOnBorrow = testOnBorrow; + } + + public void setTestOnConnect(boolean testOnConnect) + { + this.testOnConnect = testOnConnect; + } + + public void setTestOnReturn(boolean testOnReturn) + { + this.testOnReturn = testOnReturn; + } + + public void setTestWhileIdle(boolean testWhileIdle) + { + this.testWhileIdle = testWhileIdle; + } + + public void setSocketTimeout(int socketTimeOut) + { + this.socketTimeOut = socketTimeOut; + } + + /** + * @return the maxTotal + */ + public int getMaxTotal() + { + return maxTotal; + } + + /** + * @param maxTotal + * the maxTotal to set + */ + public void setMaxTotal(int maxTotal) + { + this.maxTotal = maxTotal; + } + + /** + * @return the maxActive + */ + public int getMaxActive() + { + return maxActive; + } + + /** + * @return the maxIdle + */ + public int getMaxIdle() + { + return maxIdle; + } + + /** + * @return the minIdle + */ + public int getMinIdle() + { + return minIdle; + } + + /** + * @param maxActive + * the maxActive to set + */ + public void setMaxActive(int maxActive) + { + this.maxActive = maxActive; + } + + /** + * @param maxIdle + * the maxIdle to set + */ + public void setMaxIdle(int maxIdle) + { + this.maxIdle = maxIdle; + } + + /** + * @param minIdle + * the minIdle to set + */ + public void setMinIdle(int minIdle) + { + this.minIdle = minIdle; + } + + /** + * @return the socketTimeOut + */ + public int getSocketTimeOut() + { + return socketTimeOut; + } + + /** + * @param socketTimeOut + * the socketTimeOut to set + */ + public void setSocketTimeOut(int socketTimeOut) + { + this.socketTimeOut = socketTimeOut; + } + + /** + * @return the initialSize + */ + public int getInitialSize() + { + return initialSize; + } + + /** + * @return the testOnBorrow + */ + public boolean isTestOnBorrow() + { + return testOnBorrow; + } + + /** + * @return the testOnConnect + */ + public boolean isTestOnConnect() + { + return testOnConnect; + } + + /** + * @return the testOnReturn + */ + public boolean isTestOnReturn() + { + return testOnReturn; + } + + /** + * @return the testWhileIdle + */ + public boolean isTestWhileIdle() + { + return testWhileIdle; + } + + public HostFailoverPolicy getHostFailoverPolicy() + { + return this.hostFailoverPolicy; + } + + public void setHostFailoverPolicy(HostFailoverPolicy hostFailoverPolicy) + { + this.hostFailoverPolicy = hostFailoverPolicy; + } + + public boolean isRetryHost() + { + return retryHost; + } + + public void setRetryHost(boolean retryHost) + { + this.retryHost = retryHost; + } + + @Override + public String getUser() + { + return this.userName; + } + + @Override + public String getPassword() + { + return this.password; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public void setPassword(String password) + { + this.password = password; + } + + public void setMaxWait(int maxWait) + { + this.maxWait = maxWait; + } + + public int getMaxWait() + { + return this.maxWait; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHostConfiguration.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHostConfiguration.java new file mode 100644 index 000000000..29c2a6aa6 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraHostConfiguration.java @@ -0,0 +1,289 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CopyOnWriteArrayList; + +import net.dataforte.cassandra.pool.HostFailoverPolicy; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.config.CassandraPropertyReader.CassandraSchemaMetadata; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection.Server; +import com.impetus.kundera.service.Host; +import com.impetus.kundera.service.HostConfiguration; + +/** + * Holds host configuration for cassandra specific settings. + * + * @author Kuldeep.Mishra + * + */ +public class CassandraHostConfiguration extends HostConfiguration +{ + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(CassandraHostConfiguration.class); + + public CassandraHostConfiguration(Map externalProperties, CassandraSchemaMetadata csmd, String persistenceUnit) + { + super(externalProperties, csmd != null ? csmd.getConnectionServers() : new ArrayList(), persistenceUnit); + String property = csmd.getConnectionProperties().getProperty(Constants.RETRY_DELAY); + if (StringUtils.isNumeric(property)) + { + retryDelay = Integer.parseInt(property); + } + } + + protected void buildHosts(List servers, List hostsList) + { + List cassandraHosts = new CopyOnWriteArrayList(); + for (Server server : servers) + { + String host = server.getHost(); + String portAsString = server.getPort(); + onValidation(host, portAsString); + Properties serverProperties = server.getProperties(); + CassandraHost cassandraHost = new CassandraHost(host, Integer.parseInt(portAsString)); + setConfig(cassandraHost, serverProperties, null); + cassandraHosts.add(cassandraHost); + hostsList.add(cassandraHost); + } + } + + protected void buildHosts(String hosts, String portAsString, List hostsList) + { + String[] hostVals = hosts.split(","); + List cassandraHosts = new CopyOnWriteArrayList(); + for (int x = 0; x < hostVals.length; x++) + { + String host = hostVals[x].trim(); + onValidation(host, portAsString); + int port = Integer.parseInt(portAsString); + CassandraHost cassandraHost = port == CassandraHost.DEFAULT_PORT ? new CassandraHost(host) + : new CassandraHost(host, port); + setConfig(cassandraHost, persistenceUnitMetadata.getProperties(), externalProperties); + cassandraHosts.add(cassandraHost); + hostsList.add(cassandraHost); + } + } + + @Override + protected void setConfig(Host host, Properties props, Map puProperties) + { + CassandraHost cassandraHost = (CassandraHost) host; + String maxActivePerNode = null; + String maxIdlePerNode = null; + String minIdlePerNode = null; + String maxTotal = null; + String testOnBorrow = null; + String testWhileIdle = null; + String testOnConnect = null; + String testOnReturn = null; + String socketTimeOut = null; + String userName = null; + String password = null; + String maxWaitInMilli = null; + if (puProperties != null) + { + maxActivePerNode = (String) puProperties.get(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + maxIdlePerNode = (String) puProperties.get(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_IDLE); + minIdlePerNode = (String) puProperties.get(PersistenceProperties.KUNDERA_POOL_SIZE_MIN_IDLE); + maxTotal = (String) puProperties.get(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_TOTAL); + testOnBorrow = (String) puProperties.get(CassandraConstants.TEST_ON_BORROW); + testOnConnect = (String) puProperties.get(CassandraConstants.TEST_ON_CONNECT); + testOnReturn = (String) puProperties.get(CassandraConstants.TEST_ON_RETURN); + testWhileIdle = (String) puProperties.get(CassandraConstants.TEST_WHILE_IDLE); + socketTimeOut = (String) puProperties.get(CassandraConstants.SOCKET_TIMEOUT); + userName = (String) puProperties.get(PersistenceProperties.KUNDERA_USERNAME); + password = (String) puProperties.get(PersistenceProperties.KUNDERA_PASSWORD); + maxWaitInMilli = (String) puProperties.get(CassandraConstants.MAX_WAIT); + } + + if (maxActivePerNode == null) + { + maxActivePerNode = props.getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + } + if (maxIdlePerNode == null) + { + maxIdlePerNode = props.getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_IDLE); + } + if (minIdlePerNode == null) + { + minIdlePerNode = props.getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MIN_IDLE); + } + if (maxTotal == null) + { + maxTotal = props.getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_TOTAL); + } + if (maxWaitInMilli == null) + { + maxWaitInMilli = props.getProperty(CassandraConstants.MAX_WAIT); + } + + if (userName == null) + { + userName = (String) props.get(PersistenceProperties.KUNDERA_USERNAME); + password = (String) props.get(PersistenceProperties.KUNDERA_PASSWORD); + } + try + { + if (!StringUtils.isEmpty(maxActivePerNode)) + { + cassandraHost.setInitialSize(Integer.parseInt(maxActivePerNode)); + cassandraHost.setMaxActive(Integer.parseInt(maxActivePerNode)); + } + + if (!StringUtils.isEmpty(maxIdlePerNode)) + { + cassandraHost.setMaxIdle(Integer.parseInt(maxIdlePerNode)); + } + + if (!StringUtils.isEmpty(minIdlePerNode)) + { + cassandraHost.setMinIdle(Integer.parseInt(minIdlePerNode)); + } + + if (!StringUtils.isEmpty(maxTotal)) + { + cassandraHost.setMaxActive(Integer.parseInt(maxTotal)); + } + if (!StringUtils.isEmpty(maxWaitInMilli)) + { + cassandraHost.setMaxWait(Integer.parseInt(maxWaitInMilli)); + } + + if (testOnBorrow == null) + { + testOnBorrow = props.getProperty(CassandraConstants.TEST_ON_BORROW); + } + if (testOnConnect == null) + { + testOnConnect = props.getProperty(CassandraConstants.TEST_ON_CONNECT); + } + if (testOnReturn == null) + { + testOnReturn = props.getProperty(CassandraConstants.TEST_ON_RETURN); + } + if (testWhileIdle == null) + { + testWhileIdle = props.getProperty(CassandraConstants.TEST_WHILE_IDLE); + } + if (socketTimeOut == null) + { + socketTimeOut = props.getProperty(CassandraConstants.SOCKET_TIMEOUT); + } + + cassandraHost.setTestOnBorrow(Boolean.parseBoolean(testOnBorrow)); + cassandraHost.setTestOnConnect(Boolean.parseBoolean(testOnConnect)); + cassandraHost.setTestOnReturn(Boolean.parseBoolean(testOnReturn)); + cassandraHost.setTestWhileIdle(Boolean.parseBoolean(testWhileIdle)); + cassandraHost.setHostFailoverPolicy(getFailoverPolicy(props.getProperty(Constants.FAILOVER_POLICY))); + cassandraHost.setRetryHost(Boolean.parseBoolean(props.getProperty(Constants.RETRY))); + cassandraHost.setUserName(userName); + cassandraHost.setPassword(password); + + if (!StringUtils.isEmpty(socketTimeOut)) + { + cassandraHost.setSocketTimeout(Integer.parseInt(socketTimeOut)); + } + else + { + cassandraHost.setSocketTimeout(CassandraHost.DEFAULT_SHOCKET_TIMEOUT); + } + } + catch (NumberFormatException e) + { + logger.warn("Some Connection pool related property couldn't be parsed. Default pool policy would be used"); + } + } + + /** + * + * @return Host array + */ + public List getCassandraHosts() + { + return hostsList; + } + + /** + * Resolve failover policy for Cassandra thrift. + * + * @param failoverOption + * @return + */ + private HostFailoverPolicy getFailoverPolicy(String failoverOption) + { + if (failoverOption != null) + { + if (Constants.FAIL_FAST.equals(failoverOption)) + { + return HostFailoverPolicy.FAIL_FAST; + } + else if (Constants.ON_FAIL_TRY_ALL_AVAILABLE.equals(failoverOption)) + { + return HostFailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE; + } + else if (Constants.ON_FAIL_TRY_ONE_NEXT_AVAILABLE.equals(failoverOption)) + { + return HostFailoverPolicy.ON_FAIL_TRY_ONE_NEXT_AVAILABLE; + } + else + { + logger.warn("Invalid failover policy {}, using default {} ", failoverOption, + HostFailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE.name()); + return HostFailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE; + } + } + return HostFailoverPolicy.ON_FAIL_TRY_ALL_AVAILABLE; + } + + /** + * + * @return + */ + public int getRetryDelay() + { + return retryDelay; + } + + /** + * + * @param host + * @param port + * @return CassandraHosts + */ + public CassandraHost getCassandraHost(String host, int port) + { + for (Host cassandraHost : hostsList) + { + if (((CassandraHost) cassandraHost).equals(new CassandraHost(host, port))) + { + return (CassandraHost) cassandraHost; + } + } + return null; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraRetryService.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraRetryService.java new file mode 100644 index 000000000..9ba843765 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/service/CassandraRetryService.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.service; + +import java.util.Iterator; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.cassandra.pelops.PelopsUtils; +import com.impetus.client.cassandra.thrift.ThriftClientFactory; +import com.impetus.kundera.loader.ClientFactory; +import com.impetus.kundera.service.Host; +import com.impetus.kundera.service.HostConfiguration; +import com.impetus.kundera.service.policy.RetryService; + +/** + * Cassandra retry service, retries for downed cassandra server with a fix + * delay, and add it to hostspool map when it up. + * + * @author Kuldeep.Mishra + * + */ +public class CassandraRetryService extends RetryService +{ + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(ThriftClientFactory.class); + + private LinkedBlockingQueue downedHostQueue; + + private ClientFactory clientFactory; + + public CassandraRetryService(HostConfiguration configuration, ClientFactory clientFactory) + { + super(((CassandraHostConfiguration) configuration).getRetryDelay()); + downedHostQueue = new LinkedBlockingQueue(); + this.clientFactory = clientFactory; + sf = executor.scheduleWithFixedDelay(new RetryRunner(), this.retryDelayInSeconds, this.retryDelayInSeconds, + TimeUnit.SECONDS); + } + + @Override + protected boolean verifyConnection(Host host) + { + return PelopsUtils.verifyConnection(host.getHost(), host.getPort()); + } + + class RetryRunner implements Runnable + { + + @Override + public void run() + { + if (!downedHostQueue.isEmpty()) + { + try + { + retryDownedHosts(); + } + catch (Throwable t) + { + logger.error("Error while retrying downed hosts caused by : ", t); + } + } + } + + private void retryDownedHosts() + { + Iterator iter = downedHostQueue.iterator(); + while (iter.hasNext()) + { + CassandraHost host = iter.next(); + + if (host == null) + { + continue; + } + + boolean reconnected = verifyConnection(host); + if (reconnected) + { + if (clientFactory instanceof ThriftClientFactory) + { + ((ThriftClientFactory) clientFactory).addCassandraHost(host); + } + else + { + ((PelopsClientFactory) clientFactory).addCassandraHost(host); + } + iter.remove(); + } + } + } + } + + public void add(final CassandraHost cassandraHost) + { + downedHostQueue.add(cassandraHost); + + // schedule a check of this host immediately, + executor.submit(new Runnable() + { + @Override + public void run() + { + if (verifyConnection(cassandraHost)) + { + if (clientFactory instanceof ThriftClientFactory + && ((ThriftClientFactory) clientFactory).addCassandraHost(cassandraHost) + || clientFactory instanceof PelopsClientFactory + && ((PelopsClientFactory) clientFactory).addCassandraHost(cassandraHost)) + { + downedHostQueue.remove(cassandraHost); + } + } + } + }); + } + + @Override + public void shutdown() + { + downedHostQueue.clear(); + if (sf != null) + { + sf.cancel(true); + } + if (executor != null) + { + executor.shutdownNow(); + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/CQLTranslator.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/CQLTranslator.java new file mode 100644 index 000000000..9102e9c95 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/CQLTranslator.java @@ -0,0 +1,710 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift; + +import java.lang.reflect.Field; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.cassandra.db.marshal.BooleanType; +import org.apache.cassandra.db.marshal.BytesType; +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.db.marshal.DateType; +import org.apache.cassandra.db.marshal.DecimalType; +import org.apache.cassandra.db.marshal.DoubleType; +import org.apache.cassandra.db.marshal.FloatType; +import org.apache.cassandra.db.marshal.Int32Type; +import org.apache.cassandra.db.marshal.IntegerType; +import org.apache.cassandra.db.marshal.ListType; +import org.apache.cassandra.db.marshal.LongType; +import org.apache.cassandra.db.marshal.MapType; +import org.apache.cassandra.db.marshal.SetType; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.db.marshal.UUIDType; + +import antlr.collections.List; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * CQL translator interface, to translate all CRUD operations into CQL queries. + * In case compound primary key is boolean, we need to + * $COLUMNS,$COLUMNFAMILY,$COLUMNVALUES : They need to be comma separated. + * $COLUMNVALUES : It has to be according to data type(add "'" only for + * text/string) + * + * @author vivek.mishra + */ +public final class CQLTranslator +{ + public static final String CREATE_COLUMNFAMILY_QUERY = "CREATE COLUMNFAMILY $COLUMNFAMILY ($COLUMNS"; + + public static final String ADD_PRIMARYKEY_CLAUSE = " , PRIMARY KEY($COLUMNS))"; + + public static final String SELECTALL_QUERY = "SELECT * FROM $COLUMNFAMILY"; + + public static final String ADD_WHERE_CLAUSE = " WHERE "; + + public static final String SELECT_QUERY = "SELECT $COLUMNS FROM $COLUMNFAMILY"; + + public static final String INSERT_QUERY = " INSERT INTO $COLUMNFAMILY($COLUMNS) VALUES($COLUMNVALUES) "; + + public static final String DELETE_QUERY = "DELETE FROM $COLUMNFAMILY"; + + public static final String COLUMN_FAMILY = "$COLUMNFAMILY"; + + public static final String COLUMNS = "$COLUMNS"; + + public static final String COLUMN_VALUES = "$COLUMNVALUES"; + + public static final String AND_CLAUSE = " AND "; + + public static final String EQ_CLAUSE = "="; + + public static final String WITH_CLAUSE = " WITH "; + + public static final String QUOTE_STR = "'"; + + public static final String LIMIT = " LIMIT "; + + public static final String CREATE_INDEX_QUERY = "CREATE INDEX ON $COLUMNFAMILY ($COLUMNS)"; + + public static final String BATCH_QUERY = "BEGIN BATCH $STATEMENT "; + + public static final String STATEMENT = "$STATEMENT"; + + public static final String APPLY_BATCH = " APPLY BATCH"; + + public static final String USING_CONSISTENCY = "$USING CONSISTENCY"; + + public static final String CONSISTENCY_LEVEL = "$CONSISTENCYLEVEL"; + + public static final String DROP_TABLE = "drop columnfamily $COLUMN_FAMILY"; + + public static final String UPDATE_QUERY = "UPDATE $COLUMNFAMILY "; + + public static final String ADD_SET_CLAUSE = "SET "; + + public static final String COMMA_STR = ", "; + + public static final String INCR_COUNTER = "+"; + + public static final String TOKEN="token("; + + public static final String CLOSE_BRACKET=")"; + + public CQLTranslator() + { + + } + + public static enum TranslationType + { + COLUMN, VALUE, ALL; + } + + /** + * Prepares column name or column values. + * + * @param record + * entity. + * @param entityMetadata + * entity meta data + * @param type + * translation type. + * @param externalProperties + * @return Map containing translation type as key and string as translated + * CQL string. + */ + public HashMap prepareColumnOrColumnValues(final Object record, + final EntityMetadata entityMetadata, TranslationType type, Map externalProperties) + { + HashMap parsedColumnOrColumnValue = new HashMap(); + if (type == null) + { + throw new TranslationException("Please specify TranslationType: either COLUMN or VALUE"); + } + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + Class entityClazz = entityMetadata.getEntityClazz(); + EntityType entityType = metaModel.entity(entityClazz); + + StringBuilder builder = new StringBuilder(); + StringBuilder columnBuilder = new StringBuilder(); + + onTranslation(record, entityMetadata, type, metaModel, entityClazz, entityType, builder, columnBuilder, + externalProperties); + + if (type.equals(TranslationType.ALL) || type.equals(TranslationType.VALUE)) + { + builder.deleteCharAt(builder.length() - 1); + } + + if (type.equals(TranslationType.ALL) || type.equals(TranslationType.COLUMN)) + { + columnBuilder.deleteCharAt(columnBuilder.length() - 1); + } + + parsedColumnOrColumnValue.put(TranslationType.COLUMN, columnBuilder.toString()); + + parsedColumnOrColumnValue.put(TranslationType.VALUE, builder.toString()); + + return parsedColumnOrColumnValue; + } + + public static String getCQLType(String internalClazz) + { + return InternalToCQLMapper.getType(internalClazz); + } + + public static String getKeyword(String property) + { + return CQLKeywordMapper.getType(property); + } + + /** + * On translation to column name or column value based on translation type. + * + * @param record + * record + * @param m + * entity metadata + * @param type + * translation type + * @param metaModel + * meta model + * @param entityClazz + * entity class + * @param entityType + * entity type + * @param builder + * column value builder + * @param columnBuilder + * column name builder + * @param externalProperties + */ + private void onTranslation(final Object record, final EntityMetadata m, TranslationType type, + MetamodelImpl metaModel, Class entityClazz, EntityType entityType, StringBuilder builder, + StringBuilder columnBuilder, Map externalProperties) + { + for (Field field : entityClazz.getDeclaredFields()) + { + if (metaModel.isEmbeddable(field.getType())) + { + if (field.getType().equals(m.getIdAttribute().getBindableJavaType())) + { + // builder. + // Means it is a compound key! As other + // iterate for it's fields to populate it's values in order! + EmbeddableType compoundKey = metaModel.embeddable(field.getType()); + Object compoundKeyObj = PropertyAccessorHelper.getObject(record, field); + for (Field compositeColumn : field.getType().getDeclaredFields()) + { + if (!ReflectUtils.isTransientOrStatic(compositeColumn)) + { + onTranslation(type, builder, columnBuilder, + ((AbstractAttribute) (compoundKey.getAttribute(compositeColumn.getName()))) + .getJPAColumnName(), compoundKeyObj, compositeColumn); + } + } + } + else + { + throw new PersistenceException( + "Super columns are not supported via cql for compound/composite keys!"); + } + } + else + { + if (!ReflectUtils.isTransientOrStatic(field) + && m.getIdAttribute().getName().equals(entityType.getAttribute(field.getName()).getName())) + { + onTranslation(type, builder, columnBuilder, + CassandraUtilities.getIdColumnName(m, externalProperties), record, field); + } + else if (!ReflectUtils.isTransientOrStatic(field)) + { + AbstractAttribute attrib = (AbstractAttribute) entityType.getAttribute(field.getName()); + + if (!attrib.isAssociation()) + { + onTranslation(type, builder, columnBuilder, attrib.getJPAColumnName(), record, field); + } + } + } + } + } + + /** + * Build where clause with @ EQ_CLAUSE} clause. + * + * @param builder + * @param field + * @param member + * @param entity + */ + public void buildWhereClause(StringBuilder builder, String field, Field member, Object entity) + { + builder = ensureCase(builder, field); + builder.append(EQ_CLAUSE); + appendColumnValue(builder, entity, member); + builder.append(AND_CLAUSE); + } + + /** + * Build where clause with given clause. + * + * @param builder + * @param field + * @param value + * @param clause + */ + public void buildWhereClause(StringBuilder builder, Class fieldClazz, String field, Object value, String clause) + { + builder = ensureCase(builder, field); + builder.append(clause); + appendValue(builder, fieldClazz, value, false); + builder.append(AND_CLAUSE); + } + + /** + * Builds set clause for a given counter field. + * + * @param builder + * @param field + * @param value + */ + public void buildSetClauseForCounters(StringBuilder builder, String field, Object value) + { + builder = ensureCase(builder, field); + builder.append(EQ_CLAUSE); + builder = ensureCase(builder, field); + builder.append(INCR_COUNTER); + appendValue(builder, value.getClass(), value, false); + builder.append(COMMA_STR); + } + + /** + * Ensures case for corresponding column name. + * + * @param builder + * column name builder. + * @param fieldName + * column name. + * @return builder object with appended column name. + */ + public StringBuilder ensureCase(StringBuilder builder, String fieldName) + { + builder.append("\""); + builder.append(fieldName); + builder.append("\""); + return builder; + + } + + /** + * Translates input object and corresponding field based on: a) ALL : + * translate both column name and column value. b) COlUMN: translates column + * name only. c) VALUE: translates column value only. + * + * @param type + * translation type. + * @param builder + * column value builder object. + * @param columnBuilder + * column name builder object. + * @param columnName + * column name. + * @param record + * value object. + * @param column + * value column name. + */ + private void onTranslation(TranslationType type, StringBuilder builder, StringBuilder columnBuilder, + String columnName, Object record, Field column) + { + switch (type) + { + case ALL: + if (appendColumnValue(builder, record, column)) + { + builder.append(","); + appendColumnName(columnBuilder, columnName); + columnBuilder.append(","); // because only key columns + } + break; + + case COLUMN: + + appendColumnName(columnBuilder, columnName); + columnBuilder.append(","); // because only key columns + break; + + case VALUE: + + if (appendColumnValue(builder, record, column)) + { + builder.append(","); // because only key columns + } + break; + } + } + + /** + * Appends column value with parametrised builder object. Returns true if + * value is present. + * + * @param builder + * @param valueObj + * @param column + * @return true if value is not null,else false. + */ + private boolean appendColumnValue(StringBuilder builder, Object valueObj, Field column) + { + Object value = PropertyAccessorHelper.getObject(valueObj, column); + boolean isPresent = false; + isPresent = appendValue(builder, column.getType(), value, isPresent); + return isPresent; + } + + /** + * Appends value to builder object for given class type + * + * @param builder + * string builder. + * @param fieldClazz + * field class. + * @param value + * value to be appended. + * @param isPresent + * if field is present. + * @return true, if value is not null else false. + */ + public boolean appendValue(StringBuilder builder, Class fieldClazz, Object value, boolean isPresent) + { + if (value != null) + { + if (List.class.isAssignableFrom(fieldClazz)) + { + isPresent = appendList(builder, value); + } + + else if (Set.class.isAssignableFrom(fieldClazz)) + { + isPresent = appendSet(builder, value); + } + + else if (Map.class.isAssignableFrom(fieldClazz)) + { + isPresent = appendMap(builder, value); + } + else + { + isPresent = true; + appendValue(builder, fieldClazz, value); + } + } + return isPresent; + } + + /** + * Appends a object of type {@link java.util.List} + * @param builder + * @param value + * @return + */ + private boolean appendList(StringBuilder builder, Object value) + { + boolean isPresent; + isPresent = true; + Collection collection = ((Collection) value); + if(! collection.isEmpty()) + { + builder.append("["); + for(Object o : collection) + { + if(o != null) + { + appendValue(builder, o.getClass(), o); + } + builder.append(","); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("]"); + } + return isPresent; + } + + /** + * Appends a object of type {@link java.util.Map} + * @param builder + * @param value + * @return + */ + private boolean appendSet(StringBuilder builder, Object value) + { + boolean isPresent; + isPresent = true; + Collection collection = ((Collection) value); + if(! collection.isEmpty()) + { + builder.append("{"); + for(Object o : collection) + { + if(o != null) + { + appendValue(builder, o.getClass(), o); + } + builder.append(","); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + } + return isPresent; + } + + /** + * Appends a object of type {@link java.util.List} + * @param builder + * @param value + * @return + */ + private boolean appendMap(StringBuilder builder, Object value) + { + boolean isPresent; + isPresent = true; + Map map = ((Map) value); + if(! map.isEmpty()) + { + builder.append("{"); + for(Object mapKey : map.keySet()) + { + Object mapValue = map.get(mapKey); + if(mapKey != null && mapValue != null) + { + appendValue(builder, mapKey.getClass(), mapKey); + builder.append(":"); + appendValue(builder, mapValue.getClass(), mapValue); + } + builder.append(","); + } + builder.deleteCharAt(builder.length() - 1); + builder.append("}"); + } + return isPresent; + } + + /** + * @param builder + * @param fieldClazz + * @param value + */ + private void appendValue(StringBuilder builder, Class fieldClazz, Object value) + { + if (fieldClazz.isAssignableFrom(String.class) || isDate(fieldClazz) || fieldClazz.isAssignableFrom(char.class) + || fieldClazz.isAssignableFrom(Character.class) || value instanceof Enum) + { + + if (fieldClazz.isAssignableFrom(String.class)) + { + // To allow escape character + value = ((String) value).replaceAll("'", "''"); + } + builder.append("'"); + + if (isDate(fieldClazz)) // For CQL, date has to + // be in date.getTime() + { + builder.append(PropertyAccessorFactory.getPropertyAccessor(fieldClazz).toString(value)); + } + else if (value instanceof Enum) + { + builder.append(((Enum) value).name()); + } + else + { + builder.append(value); + } + builder.append("'"); + } + else + { + builder.append(value); + } + } + + /** + * Appends column name and ensure case sensitivity. + * + * @param builder + * string builder. + * @param columnName + * column name. + */ + public void appendColumnName(StringBuilder builder, String columnName) + { + ensureCase(builder, columnName); + } + + /** + * Appends column name and data type also ensures case sensitivity. + * + * @param builder + * string builder + * @param columnName + * column name + * @param dataType + * data type. + */ + public void appendColumnName(StringBuilder builder, String columnName, String dataType) + { + ensureCase(builder, columnName); + builder.append(" "); // because only key columns + builder.append(dataType); + } + + /** + * Validates if input class is of type input. + * + * @param clazz + * class + * + * @return true, if it is a date field class. + */ + private boolean isDate(Class clazz) + { + return clazz.isAssignableFrom(Date.class) || clazz.isAssignableFrom(java.sql.Date.class) + || clazz.isAssignableFrom(Timestamp.class) || clazz.isAssignableFrom(Time.class) + || clazz.isAssignableFrom(Calendar.class); + } + + /** + * Maps internal data type of cassandra to CQL type representation. + * + * @author vivek.mishra + */ + private static class InternalToCQLMapper + { + /** The Mapper. */ + private final static Map mapper; + + static + { + Map validationClassMapper = new HashMap(); + // TODO: support for ascii is missing! + + // putting possible combination into map. + + validationClassMapper.put(UTF8Type.class.getSimpleName(), "text"); + + validationClassMapper.put(IntegerType.class.getSimpleName(), "int"); + + validationClassMapper.put(Int32Type.class.getSimpleName(), "int"); + + validationClassMapper.put(DoubleType.class.getSimpleName(), "double"); + + validationClassMapper.put(BooleanType.class.getSimpleName(), "boolean"); + + validationClassMapper.put(LongType.class.getSimpleName(), "bigint"); + + validationClassMapper.put(BytesType.class.getSimpleName(), "blob"); + + validationClassMapper.put(FloatType.class.getSimpleName(), "float"); + + // missing + validationClassMapper.put(CounterColumnType.class.getSimpleName(), "counter"); + + validationClassMapper.put(DecimalType.class.getSimpleName(), "decimal"); + + validationClassMapper.put(UUIDType.class.getSimpleName(), "uuid"); + + validationClassMapper.put(DateType.class.getSimpleName(), "timestamp"); + + //collection types + validationClassMapper.put(ListType.class.getSimpleName(), "list"); + validationClassMapper.put(SetType.class.getSimpleName(), "set"); + validationClassMapper.put(MapType.class.getSimpleName(), "map"); + + mapper = Collections.synchronizedMap(validationClassMapper); + } + + private static final String getType(final String internalClassName) + { + return mapper.get(internalClassName); + } + } + + private static class CQLKeywordMapper + { + /** The Mapper. */ + private final static Map mapper = new HashMap(); + + // missing: compaction_strategy_options, + // compression_parameters,sstable_size_in_mb + static + { + mapper.put(CassandraConstants.READ_REPAIR_CHANCE, "read_repair_chance"); + mapper.put(CassandraConstants.DCLOCAL_READ_REPAIR_CHANCE, "dclocal_read_repair_chance"); + mapper.put(CassandraConstants.BLOOM_FILTER_FP_CHANCE, "bloom_filter_fp_chance"); + mapper.put(CassandraConstants.COMPACTION_STRATEGY, "compaction_strategy_class"); + mapper.put(CassandraConstants.BLOOM_FILTER_FP_CHANCE, "bloom_filter_fp_chance"); + + // mapper.put(CassandraConstants.COMPARATOR_TYPE, "comparator"); + + mapper.put(CassandraConstants.REPLICATE_ON_WRITE, "replicate_on_write"); + mapper.put(CassandraConstants.CACHING, "caching"); + // TODO: these are not supported. + // mapper.put(CassandraConstants.MAX_COMPACTION_THRESHOLD, + // "max_compaction_threshold"); + // mapper.put(CassandraConstants.MIN_COMPACTION_THRESHOLD, + // "min_compaction_threshold"); + mapper.put(CassandraConstants.COMMENT, "comment"); + mapper.put(CassandraConstants.GC_GRACE_SECONDS, "gc_grace_seconds"); + } + + private static final String getType(final String propertyName) + { + return mapper.get(propertyName); + } + } + + /** + * @param builder + */ + public void buildFilteringClause(StringBuilder builder) + { + builder.append(" ALLOW FILTERING"); + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClient.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClient.java new file mode 100644 index 000000000..32350fbfd --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClient.java @@ -0,0 +1,1058 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.PersistenceException; + +import net.dataforte.cassandra.pool.ConnectionPool; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ColumnPath; +import org.apache.cassandra.thrift.CounterColumn; +import org.apache.cassandra.thrift.CounterSuperColumn; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.IndexExpression; +import org.apache.cassandra.thrift.IndexOperator; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KeyRange; +import org.apache.cassandra.thrift.KeySlice; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.SuperColumn; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.scale7.cassandra.pelops.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.index.InvertedIndexHandler; +import com.impetus.client.cassandra.query.CassQuery; +import com.impetus.client.cassandra.thrift.ThriftClientFactory.Connection; +import com.impetus.client.cassandra.thrift.ThriftDataResultHelper.ColumnFamilyType; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.generator.TableGenerator; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.EntityReaderException; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.property.PropertyAccessor; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Kundera Client implementation for Cassandra using Thrift library + * + * @author amresh.singh + */ +public class ThriftClient extends CassandraClientBase implements Client, Batcher, TableGenerator +{ + + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(ThriftClient.class); + + /** The data handler. */ + private ThriftDataHandler dataHandler; + + /** Handler for Inverted indexing */ + private InvertedIndexHandler invertedIndexHandler; + + /** The reader. */ + private EntityReader reader; + + private ThriftClientFactory clientFactory; + + private ConnectionPool pool; + + public ThriftClient(ThriftClientFactory clientFactory, IndexManager indexManager, EntityReader reader, + String persistenceUnit, ConnectionPool pool, Map externalProperties) + { + super(persistenceUnit, externalProperties); + this.clientFactory = clientFactory; + this.persistenceUnit = persistenceUnit; + this.indexManager = indexManager; + this.dataHandler = new ThriftDataHandler(this); + this.reader = reader; + this.clientMetadata = clientFactory.getClientMetadata(); + this.invertedIndexHandler = new ThriftInvertedIndexHandler(this,MetadataUtils.useSecondryIndex(clientMetadata)); + this.pool = pool; + } + + /** + * Persists and indexes a {@link Node} to database + */ + @Override + public void persist(Node node) + { + super.persist(node); + } + + /** + * Persists a {@link Node} to database + */ + @Override + protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id, List rlHolders) + { + Connection conn = getConection(); + try + { + + // if entity is embeddable...call cql translator to get cql string! + // use thrift client to execute cql query. + + if (isCql3Enabled(entityMetadata)) + { + cqlClient.persist(entityMetadata, entity, conn.getClient(), rlHolders, + getTtlValues().get(entityMetadata.getTableName())); + } + else + { + Map>> mutationMap = new HashMap>>(); + prepareMutation(entityMetadata, entity, id, rlHolders, mutationMap); + // Write Mutation map to database + conn.getClient().batch_mutate(mutationMap, getConsistencyLevel()); + + mutationMap.clear(); + mutationMap = null; + } + + } + catch (InvalidRequestException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + catch (SchemaDisagreementException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + catch (UnsupportedEncodingException e) + { + log.error("Error while persisting record, Caused by: .", e); + throw new KunderaException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + + if (isTtlPerRequest()) + { + getTtlValues().clear(); + } + } + } + + /** + * Persists a Join table record set into database + */ + @Override + public void persistJoinTable(JoinTableData joinTableData) + { + String joinTableName = joinTableData.getJoinTableName(); + String invJoinColumnName = joinTableData.getInverseJoinColumnName(); + Map> joinTableRecords = joinTableData.getJoinTableRecords(); + + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(joinTableData.getEntityClass()); + + Connection conn = null; + try + { + for (Object key : joinTableRecords.keySet()) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor((Field) entityMetadata + .getIdAttribute().getJavaMember()); + byte[] rowKey = accessor.toBytes(key); + + Set values = joinTableRecords.get(key); + List columns = new ArrayList(); + + // Create Insertion List + List insertionList = new ArrayList(); + Class columnType = null; + for (Object value : values) + { + Column column = new Column(); + column.setName(PropertyAccessorFactory.STRING.toBytes(invJoinColumnName + + Constants.JOIN_COLUMN_NAME_SEPARATOR + value)); + // column.setValue(PropertyAccessorFactory.STRING.toBytes((String) + // value)); + column.setValue(PropertyAccessorHelper.getBytes(value)); + + column.setTimestamp(System.currentTimeMillis()); + columnType = value.getClass(); + columns.add(column); + + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setColumn(column)); + insertionList.add(mut); + } + + createIndexesOnColumns(entityMetadata, joinTableName, columns, columnType); + + // Create Mutation Map + Map> columnFamilyValues = new HashMap>(); + columnFamilyValues.put(joinTableName, insertionList); + Map>> mulationMap = new HashMap>>(); + mulationMap.put(ByteBuffer.wrap(rowKey), columnFamilyValues); + + // Write Mutation map to database + + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + + conn.getClient().set_keyspace(entityMetadata.getSchema()); + + conn.getClient().batch_mutate(mulationMap, getConsistencyLevel()); + } + } + catch (InvalidRequestException e) + { + log.error("Error while inserting record into join table, Caused by: .", e); + throw new PersistenceException(e); + } + catch (TException e) + { + log.error("Error while inserting record into join table, Caused by: .", e); + throw new PersistenceException(e); + } + catch (UnavailableException e) + { + log.error("Error while inserting record into join table, Caused by: .", e); + throw new PersistenceException(e); + } + catch (TimedOutException e) + { + log.error("Error while inserting record into join table, Caused by: .", e); + throw new PersistenceException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + } + + /** + * Indexes a {@link Node} to database + */ + @Override + protected void indexNode(Node node, EntityMetadata entityMetadata) + { + super.indexNode(node, entityMetadata); + + // Write to inverted index table if applicable + // setCassandraClient(); + invertedIndexHandler.write(node, entityMetadata, getPersistenceUnit(), getConsistencyLevel(), dataHandler); + } + + /** + * Finds an entity from database + */ + @Override + public Object find(Class entityClass, Object key) + { + return super.find(entityClass, key); + } + + /** + * Finds a {@link List} of entities from database + */ + @Override + public List findAll(Class entityClass, String[] columnsToSelect, Object... keys) + { + return super.findAll(entityClass, columnsToSelect, keys); + } + + /** + * Finds a {@link List} of entities from database + */ + @Override + public final List find(Class entityClass, List relationNames, boolean isWrapReq, EntityMetadata metadata, + Object... rowIds) + { + if (!isOpen()) + { + throw new PersistenceException("ThriftClient is closed."); + } + + List entities = null; + try + { + entities = dataHandler.fromThriftRow(entityClass, metadata, relationNames, isWrapReq, + getConsistencyLevel(), rowIds); + } + catch (Exception e) + { + log.error("Error while retrieving records for entity {}, row keys {}", entityClass, rowIds); + throw new KunderaException(e); + } + return entities; + } + + /** + * Finds a {@link List} of entities from database for given super columns + */ + @Override + public List find(Class entityClass, Map embeddedColumnMap) + { + return super.find(entityClass, embeddedColumnMap, dataHandler); + } + + /** + * Loads super columns from database + */ + @Override + protected final List loadSuperColumns(String keyspace, String columnFamily, String rowId, + String... superColumnNames) + { + if (!isOpen()) + throw new PersistenceException("ThriftClient is closed."); + + byte[] rowKey = rowId.getBytes(); + + SlicePredicate predicate = new SlicePredicate(); + List columnNames = new ArrayList(); + for (String superColumnName : superColumnNames) + { + columnNames.add(ByteBuffer.wrap(superColumnName.getBytes())); + } + + predicate.setColumn_names(columnNames); + + ColumnParent parent = new ColumnParent(columnFamily); + List coscList; + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + + coscList = conn.getClient().get_slice(ByteBuffer.wrap(rowKey), parent, predicate, getConsistencyLevel()); + + } + catch (InvalidRequestException e) + { + log.error("Error while getting super columns for row Key {} , Caused by: .", rowId, e); + throw new EntityReaderException(e); + } + catch (UnavailableException e) + { + log.error("Error while getting super columns for row Key {} , Caused by: .", rowId, e); + throw new EntityReaderException(e); + } + catch (TimedOutException e) + { + log.error("Error while getting super columns for row Key {} , Caused by: .", rowId, e); + throw new EntityReaderException(e); + } + catch (TException e) + { + log.error("Error while getting super columns for row Key {} , Caused by: .", rowId, e); + throw new EntityReaderException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + + List superColumns = ThriftDataResultHelper.transformThriftResult(coscList, + ColumnFamilyType.SUPER_COLUMN, null); + return superColumns; + } + + /** + * Retrieves column for a given primary key + */ + @Override + public List getColumnsById(String schemaName, String tableName, String pKeyColumnName, String columnName, + Object pKeyColumnValue, Class columnJavaType) + { + byte[] rowKey = CassandraUtilities.toBytes(pKeyColumnValue);/*pKeyColumnValue.toString().getBytes()*/; + + if (rowKey != null) + { + SlicePredicate predicate = new SlicePredicate(); + SliceRange sliceRange = new SliceRange(); + sliceRange.setStart(new byte[0]); + sliceRange.setFinish(new byte[0]); + predicate.setSlice_range(sliceRange); + + ColumnParent parent = new ColumnParent(tableName); + List results; + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + results = conn.getClient().get_slice(ByteBuffer.wrap(rowKey), parent, predicate, getConsistencyLevel()); + } + catch (InvalidRequestException e) + { + log.error("Error while getting columns for row Key {} , Caused by: .", pKeyColumnValue, e); + throw new EntityReaderException(e); + } + catch (UnavailableException e) + { + log.error("Error while getting columns for row Key {} , Caused by: .", pKeyColumnValue, e); + throw new EntityReaderException(e); + } + catch (TimedOutException e) + { + log.error("Error while getting columns for row Key {} , Caused by: .", pKeyColumnValue, e); + throw new EntityReaderException(e); + } + catch (TException e) + { + log.error("Error while getting columns for row Key {} , Caused by: .", pKeyColumnValue, e); + throw new EntityReaderException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + + List columns = ThriftDataResultHelper.transformThriftResult(results, ColumnFamilyType.COLUMN, null); + + List foreignKeys = dataHandler.getForeignKeysFromJoinTable(columnName, columns, columnJavaType); + return (List) foreignKeys; + } + return new ArrayList(); + } + + /** + * Retrieves IDs for a given column + */ + @Override + public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName, + Object columnValue, Class entityClazz) + { + List rowKeys = new ArrayList(); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entityClazz); + + SlicePredicate slicePredicate = new SlicePredicate(); + + slicePredicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), false, 1000)); + + String childIdStr = PropertyAccessorHelper.getString(columnValue); + IndexExpression ie = new IndexExpression(Bytes.fromUTF8( + columnName + Constants.JOIN_COLUMN_NAME_SEPARATOR + childIdStr).getBytes(), IndexOperator.EQ, Bytes + .fromUTF8(childIdStr).getBytes()); + + List expressions = new ArrayList(); + expressions.add(ie); + + IndexClause ix = new IndexClause(); + ix.setStart_key(Bytes.EMPTY.toByteArray()); + ix.setCount(1000); + ix.setExpressions(expressions); + + ColumnParent columnParent = new ColumnParent(tableName); + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + List keySlices = conn.getClient().get_indexed_slices(columnParent, ix, slicePredicate, + getConsistencyLevel()); + + rowKeys = ThriftDataResultHelper.getRowKeys(keySlices, metadata); + } + catch (InvalidRequestException e) + { + log.error("Error while fetching key slices of column family {} for column name {} , Caused by: .", + tableName, columnName, e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error while fetching key slices of column family {} for column name {} , Caused by: .", + tableName, columnName, e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while fetching key slices of column family {} for column name {} , Caused by: .", + tableName, columnName, e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while fetching key slices of column family {} for column name {} , Caused by: .", + tableName, columnName, e); + throw new KunderaException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + if (rowKeys != null && !rowKeys.isEmpty()) + { + return rowKeys.toArray(new Object[0]); + } + + if (log.isInfoEnabled()) + { + log.info("No record found!, returning null."); + } + return null; + } + + @Override + public List findByRelation(String colName, Object colValue, Class entityClazz) + { + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClazz); + List entities = null; + + if (isCql3Enabled(m)) + { + entities = findByRelationQuery(m, colName, colValue, entityClazz, dataHandler); + } + else + { + SlicePredicate slicePredicate = new SlicePredicate(); + slicePredicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), false, 1000)); + + IndexExpression ie = new IndexExpression(Bytes.fromUTF8(colName).getBytes(), IndexOperator.EQ, + ByteBuffer.wrap(PropertyAccessorHelper.getBytes(colValue))); + List expressions = new ArrayList(); + expressions.add(ie); + + IndexClause ix = new IndexClause(); + ix.setStart_key(Bytes.EMPTY.toByteArray()); + ix.setCount(1000); + ix.setExpressions(expressions); + ColumnParent columnParent = new ColumnParent(m.getTableName()); + + List keySlices; + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + keySlices = conn.getClient() + .get_indexed_slices(columnParent, ix, slicePredicate, getConsistencyLevel()); + } + catch (InvalidRequestException e) + { + if (e.why != null && e.why.contains("No indexed columns")) + { + return entities; + } + else + { + log.error("Error while finding relations for column family {} , Caused by: .", m.getTableName(), e); + throw new KunderaException(e); + } + } + catch (UnavailableException e) + { + log.error("Error while finding relations for column family {} , Caused by: .", m.getTableName(), e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while finding relations for column family {} , Caused by: .", m.getTableName(), e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while finding relations for column family {} , Caused by: .", m.getTableName(), e); + throw new KunderaException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + + if (keySlices != null) + { + entities = new ArrayList(keySlices.size()); + populateData(m, keySlices, entities, m.getRelationNames() != null, m.getRelationNames()); + } + } + return entities; + } + + @Override + public void delete(Object entity, Object pKey) + { + if (!isOpen()) + { + throw new PersistenceException("ThriftClient is closed."); + } + + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + + if (isCql3Enabled(metadata)) + { + String deleteQuery = onDeleteQuery(metadata, metaModel, pKey); + executeQuery(deleteQuery, metadata.getEntityClazz(), null); + } + else + { + if (metadata.isCounterColumnType()) + { + deleteRecordFromCounterColumnFamily(pKey, metadata, getConsistencyLevel()); + } + else + { + ColumnPath path = new ColumnPath(metadata.getTableName()); + + conn.getClient().remove( + ByteBuffer.wrap(CassandraUtilities.toBytes(pKey, metadata.getIdAttribute().getJavaType()) + .toByteArray()), path, System.currentTimeMillis(), getConsistencyLevel()); + } + } + + // Delete from Lucene if applicable + getIndexManager().remove(metadata, entity, pKey.toString()); + + // Delete from Inverted Index if applicable + invertedIndexHandler.delete(entity, metadata, getConsistencyLevel()); + } + catch (InvalidRequestException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", metadata.getTableName(), + pKey, e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", metadata.getTableName(), + pKey, e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", metadata.getTableName(), + pKey, e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", metadata.getTableName(), + pKey, e); + throw new KunderaException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + } + + @Override + public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) + { + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + + Properties props = persistenceUnitMetadata.getProperties(); + String keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + if (!isOpen()) + { + throw new PersistenceException("ThriftClient is closed."); + } + + Connection conn = null; + try + { + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + ColumnPath path = new ColumnPath(tableName); + // cassandra_client.remove(ByteBuffer.wrap(columnValue.toString().getBytes()), + // path, + // System.currentTimeMillis(), getConsistencyLevel()); + conn.getClient().remove( + ByteBuffer.wrap(CassandraUtilities.toBytes(columnValue, columnValue.getClass()).toByteArray()), + path, System.currentTimeMillis(), getConsistencyLevel()); + + } + catch (InvalidRequestException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", tableName, columnValue, + e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", tableName, columnValue, + e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", tableName, columnValue, + e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while deleting of column family {} for row key {}, Caused by: .", tableName, columnValue, + e); + throw new KunderaException(e); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + + } + + @Override + public EntityReader getReader() + { + return reader; + } + + @Override + public Class getQueryImplementor() + { + return CassQuery.class; + } + + @Override + public String getPersistenceUnit() + { + return super.getPersistenceUnit(); + } + + @Override + protected List getRelationHolders(Node node) + { + return super.getRelationHolders(node); + } + + @Override + public void close() + { + this.indexManager.flush(); + this.dataHandler = null; + this.invertedIndexHandler = null; + super.close(); + } + + private void populateData(EntityMetadata m, List keySlices, List entities, boolean isRelational, + List relationNames) + { + try + { + if (m.getType().isSuperColumnFamilyMetadata()) + { + List rowKeys = ThriftDataResultHelper.getRowKeys(keySlices, m); + + Object[] rowIds = rowKeys.toArray(); + entities.addAll(findAll(m.getEntityClazz(), null, rowIds)); + } + else + { + for (KeySlice keySlice : keySlices) + { + byte[] key = keySlice.getKey(); + List coscList = keySlice.getColumns(); + + List columns = ThriftDataResultHelper.transformThriftResult(coscList, + ColumnFamilyType.COLUMN, null); + + Object e = dataHandler.populateEntity( + new ThriftRow(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), key), m + .getTableName(), columns, new ArrayList(0), + new ArrayList(0), new ArrayList(0)), m, + relationNames, isRelational); + if (e != null) + { + entities.add(e); + } + } + } + } + catch (Exception e) + { + log.error("Error while populating data for relations of column family {}, Caused by: .", m.getTableName(), + e); + throw new KunderaException(e); + } + } + + /** Query related methods */ + + @Override + public List executeQuery(String cqlQuery, Class clazz, List relationalField) + { + return super.executeQuery(cqlQuery, clazz, relationalField, dataHandler); + } + + @Override + public List find(List ixClause, EntityMetadata m, boolean isRelation, List relations, + int maxResult, List columns) + { + List entities = new ArrayList(); + Connection conn = null; + try + { + // ixClause can be 0,1 or more! + SlicePredicate slicePredicate = new SlicePredicate(); + + if (columns != null && !columns.isEmpty()) + { + List asList = new ArrayList(32); + for (String colName : columns) + { + if (colName != null) + { + asList.add(Bytes.fromUTF8(colName).getBytes()); + } + } + slicePredicate.setColumn_names(asList); + } + else + { + SliceRange sliceRange = new SliceRange(); + sliceRange.setStart(Bytes.EMPTY.getBytes()); + sliceRange.setFinish(Bytes.EMPTY.getBytes()); + slicePredicate.setSlice_range(sliceRange); + } + conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + + if (ixClause.isEmpty()) + { + KeyRange keyRange = new KeyRange(maxResult); + keyRange.setStart_key(Bytes.nullSafeGet(Bytes.fromUTF8(""))); + keyRange.setEnd_key(Bytes.nullSafeGet(Bytes.fromUTF8(""))); + + if (m.isCounterColumnType()) + { + + List ks = conn.getClient().get_range_slices(new ColumnParent(m.getTableName()), + slicePredicate, keyRange, getConsistencyLevel()); + entities = onCounterColumn(m, isRelation, relations, ks); + + } + else + { + + List keySlices = conn.getClient().get_range_slices(new ColumnParent(m.getTableName()), + slicePredicate, keyRange, getConsistencyLevel()); + + if (m.getType().isSuperColumnFamilyMetadata()) + { + Map> qResults = ThriftDataResultHelper.transformThriftResult( + ColumnFamilyType.SUPER_COLUMN, keySlices, null); + entities = new ArrayList(qResults.size()); + computeEntityViaSuperColumns(m, isRelation, relations, entities, qResults); + } + else + { + Map> qResults = ThriftDataResultHelper.transformThriftResult( + ColumnFamilyType.COLUMN, keySlices, null); + entities = new ArrayList(qResults.size()); + computeEntityViaColumns(m, isRelation, relations, entities, qResults); + } + } + } + else + { + entities = new ArrayList(); + for (IndexClause ix : ixClause) + { + List keySlices = conn.getClient().get_indexed_slices(new ColumnParent(m.getTableName()), + ix, slicePredicate, getConsistencyLevel()); + + Map> qResults = ThriftDataResultHelper.transformThriftResult( + ColumnFamilyType.COLUMN, keySlices, null); + // iterate through complete map and + entities = new ArrayList(qResults.size()); + + computeEntityViaColumns(m, isRelation, relations, entities, qResults); + } + } + } + catch (InvalidRequestException irex) + { + log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), irex); + throw new PersistenceException(irex); + } + catch (UnavailableException uex) + { + log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), uex); + throw new PersistenceException(uex); + } + catch (TimedOutException tex) + { + log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), tex); + throw new PersistenceException(tex); + } + catch (TException tex) + { + log.error("Error during executing find of column family {}, Caused by: .", m.getTableName(), tex); + throw new PersistenceException(tex); + } + finally + { + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + } + return entities; + } + + @Override + public List find(EntityMetadata m, List relationNames, List conditions, + int maxResult, List columns) + { + return (List) find(conditions, m, true, relationNames, maxResult, columns); + } + + @Override + public List findByRange(byte[] minVal, byte[] maxVal, EntityMetadata m, boolean isWrapReq, List relations, + List columns, List conditions, int maxResults) throws Exception + { + SlicePredicate slicePredicate = new SlicePredicate(); + + if (columns != null && !columns.isEmpty()) + { + List asList = new ArrayList(32); + for (String colName : columns) + { + if (colName != null) + { + asList.add(Bytes.fromUTF8(colName).getBytes()); + } + } + slicePredicate.setColumn_names(asList); + } + else + { + SliceRange sliceRange = new SliceRange(); + sliceRange.setStart(Bytes.EMPTY.getBytes()); + sliceRange.setFinish(Bytes.EMPTY.getBytes()); + slicePredicate.setSlice_range(sliceRange); + } + + KeyRange keyRange = new KeyRange(maxResults); + keyRange.setStart_key(minVal == null ? "".getBytes() : minVal); + keyRange.setEnd_key(maxVal == null ? "".getBytes() : maxVal); + ColumnParent cp = new ColumnParent(m.getTableName()); + + if (conditions != null && !conditions.isEmpty()) + { + keyRange.setRow_filter(conditions); + keyRange.setRow_filterIsSet(true); + } + + Connection conn = /* PelopsUtils.getCassandraConnection(pool) */getConection(); + + List keys = conn.getClient().get_range_slices(cp, slicePredicate, keyRange, getConsistencyLevel()); + + // PelopsUtils.releaseConnection(pool, conn); + releaseConnection(conn); + + List results = null; + if (keys != null) + { + results = populateEntitiesFromKeySlices(m, isWrapReq, relations, keys, dataHandler); + } + return results; + } + + @Override + public List searchInInvertedIndex(String columnFamilyName, EntityMetadata m, + Map> indexClauseMap) + { + return invertedIndexHandler.search(m, getPersistenceUnit(), getConsistencyLevel(), indexClauseMap); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.cassandra.CassandraClientBase#getDataHandler() + */ + @Override + protected CassandraDataHandler getDataHandler() + { + return dataHandler; + } + + protected Connection getConection() + { + Connection connection = clientFactory.getConnection(pool); + return connection; + } + + protected void releaseConnection(Object conn) + { + clientFactory.releaseConnection(((Connection) conn).getPool(), ((Connection) conn).getClient()); + } + + @Override + public Long generate(TableGeneratorDiscriptor discriptor) + { + return getGeneratedValue(discriptor, getPersistenceUnit()); + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClientFactory.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClientFactory.java new file mode 100644 index 000000000..a3568b93e --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftClientFactory.java @@ -0,0 +1,387 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import net.dataforte.cassandra.pool.ConnectionPool; +import net.dataforte.cassandra.pool.PoolConfiguration; +import net.dataforte.cassandra.pool.PoolProperties; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Lists; +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.cassandra.pelops.PelopsUtils; +import com.impetus.client.cassandra.query.CassandraEntityReader; +import com.impetus.client.cassandra.schemamanager.CassandraSchemaManager; +import com.impetus.client.cassandra.service.CassandraHost; +import com.impetus.client.cassandra.service.CassandraHostConfiguration; +import com.impetus.client.cassandra.service.CassandraRetryService; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.GenericClientFactory; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.service.Host; +import com.impetus.kundera.service.HostConfiguration; +import com.impetus.kundera.service.policy.LeastActiveBalancingPolicy; +import com.impetus.kundera.service.policy.RoundRobinBalancingPolicy; + +/** + * A factory of {@link ThriftClient} Currently it uses Pelops for Connection + * pooling. Need to replace it with our own pooling. Most of the code is + * borrowed from {@link PelopsClientFactory} + * + * @author amresh.singh + */ +public class ThriftClientFactory extends GenericClientFactory +{ + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(ThriftClientFactory.class); + + protected HostConfiguration configuration; + + @Override + public SchemaManager getSchemaManager(Map externalProperty) + { + if (schemaManager == null) + { + initializePropertyReader(); +// setExternalProperties(externalProperty); + schemaManager = new CassandraSchemaManager(ThriftClientFactory.class.getName(), externalProperties); + } + return schemaManager; + } + + /** + * + */ + private void initializePropertyReader() + { + if (propertyReader == null) + { + propertyReader = new CassandraPropertyReader(externalProperties); + propertyReader.read(getPersistenceUnit()); + } + } + + @Override + public void destroy() + { + if (indexManager != null) + { + indexManager.close(); + } + if (schemaManager != null) + { + schemaManager.dropSchema(); + } + schemaManager = null; + externalProperties = null; + + for (Object connectionPool : hostPools.values()) + { + if (connectionPool != null && connectionPool.getClass().isAssignableFrom(ConnectionPool.class)) + { + ((ConnectionPool) connectionPool).close(true); + } + } + ((CassandraRetryService) hostRetryService).shutdown(); + } + + @Override + public void initialize(Map externalProperty) + { + reader = new CassandraEntityReader(); + initializePropertyReader(); + setExternalProperties(externalProperty); + String loadBalancingPolicyName = CassandraPropertyReader.csmd != null ? CassandraPropertyReader.csmd + .getConnectionProperties().getProperty(Constants.LOADBALANCING_POLICY) : null; + initializeLoadBalancer(loadBalancingPolicyName); + configuration = new CassandraHostConfiguration(externalProperties, CassandraPropertyReader.csmd, + getPersistenceUnit()); + hostRetryService = new CassandraRetryService(configuration, this); + } + + @Override + protected Object createPoolOrConnection() + { + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + + Properties props = persistenceUnitMetadata.getProperties(); + String keyspace = null; + if (externalProperties != null) + { + keyspace = (String) externalProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + + if (keyspace == null) + { + keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + + for (Host host : ((CassandraHostConfiguration) configuration).getCassandraHosts()) + { + PoolConfiguration prop = new PoolProperties(); + prop.setHost(host.getHost()); + prop.setPort(host.getPort()); + prop.setKeySpace(keyspace); + + PelopsUtils.setPoolConfigPolicy((CassandraHost) host, prop); + try + { + ConnectionPool pool = new ConnectionPool(prop); + hostPools.put(host, pool); + } + catch (TException e) + { + logger.warn("Node {} are down, Caused by {} .", host.getHost(), e.getMessage()); + if (host.isRetryHost()) + { + logger.warn("Scheduling node for future retry"); + ((CassandraRetryService) hostRetryService).add((CassandraHost) host); + } + } + } + return null; + } + + @Override + protected Client instantiateClient(String persistenceUnit) + { + ConnectionPool pool = getPoolUsingPolicy(); + return new ThriftClient(this, indexManager, reader, persistenceUnit, pool, externalProperties); + } + + /** + * + * @return pool an the basis of LoadBalancing policy. + */ + private ConnectionPool getPoolUsingPolicy() + { + if (!hostPools.isEmpty()) + { + return (ConnectionPool) loadBalancingPolicy.getPool(hostPools.values()); + } + throw new KunderaException("All hosts are down. please check servers manully."); + } + + @Override + public boolean isThreadSafe() + { + return false; + } + + /** + * + * @param host + * @param port + * @return + */ + private ConnectionPool getNewPool(String host, int port) + { + CassandraHost cassandraHost = ((CassandraHostConfiguration) configuration).getCassandraHost(host, port); + hostPools.remove(cassandraHost); + return getPoolUsingPolicy(); + } + + @Override + protected void initializeLoadBalancer(String loadBalancingPolicyName) + { + if (loadBalancingPolicyName != null) + { + switch (LoadBalancer.getValue(loadBalancingPolicyName)) + { + case ROUNDROBIN: + loadBalancingPolicy = new RoundRobinBalancingPolicy(); + break; + case LEASTACTIVE: + loadBalancingPolicy = new ThriftLeastActiveBalancingPolcy(); + break; + default: + loadBalancingPolicy = new RoundRobinBalancingPolicy(); + break; + } + } + loadBalancingPolicy = new RoundRobinBalancingPolicy(); + } + + Connection getConnection(ConnectionPool pool) + { + ConnectionPool connectionPool = pool; + boolean success = false; + while (!success) + { + try + { + success = true; + Cassandra.Client client = connectionPool.getConnection(); + if(logger.isInfoEnabled()) + { + logger.info("Retruning connection of {} :{} .", pool.getPoolProperties().getHost(), pool + .getPoolProperties().getPort()); + } + + return new Connection(client, connectionPool); + } + catch (TException te) + { + success = false; + logger.warn("{} :{} host appears to be down, trying for next ", pool.getPoolProperties().getHost(), + pool.getPoolProperties().getPort()); + connectionPool = getNewPool(pool.getPoolProperties().getHost(), pool.getPoolProperties().getPort()); + } + } + + throw new KunderaException("All hosts are down. please check servers manully."); + } + + void releaseConnection(ConnectionPool pool, Cassandra.Client conn) + { + if (pool != null && conn != null) + { + pool.release(conn); + } + } + + /** + * Adds a pool in hostPools map for given host. + * + * @param cassandraHost + * @return true id added successfully. + */ + public boolean addCassandraHost(CassandraHost cassandraHost) + { + String keysapce = KunderaMetadataManager.getPersistenceUnitMetadata(getPersistenceUnit()).getProperties() + .getProperty(PersistenceProperties.KUNDERA_KEYSPACE); + PoolConfiguration prop = new PoolProperties(); + prop.setHost(cassandraHost.getHost()); + prop.setPort(cassandraHost.getPort()); + prop.setKeySpace(keysapce); + + PelopsUtils.setPoolConfigPolicy(cassandraHost, prop); + try + { + if (logger.isInfoEnabled()) + { + logger.info("Initializing connection for keyspace {},host {},port {}", keysapce, + cassandraHost.getHost(), cassandraHost.getPort()); + } + ConnectionPool pool = new ConnectionPool(prop); + hostPools.put(cassandraHost, pool); + return true; + } + catch (TException e) + { + logger.warn("Node " + cassandraHost.getHost() + " are still down"); + return false; + } + } + + /** + * Extends LeastActiveBalancingPolicy class and provide own implementation + * in order to support least active balancing policy. + * + * @author Kuldeep.Mishra + * + */ + private class ThriftLeastActiveBalancingPolcy extends LeastActiveBalancingPolicy + { + + /** + * + * @return pool object for host which has least active connections + * determined by maxActive connection. + * + */ + @Override + public Object getPool(Collection pools) + { + List vals = Lists.newArrayList(pools); + Collections.shuffle(vals); + Collections.sort(vals, new ShufflingCompare()); + Collections.reverse(vals); + Iterator iterator = vals.iterator(); + Object concurrentConnectionPool = iterator.next(); + return concurrentConnectionPool; + } + + /** + * Compares two pool object on the basis of their maxActive connection. + * + * @author Kuldeep Mishra + * + */ + private final class ShufflingCompare implements Comparator + { + public int compare(Object o1, Object o2) + { + PoolConfiguration props1 = ((ConnectionPool) o1).getPoolProperties(); + PoolConfiguration props2 = ((ConnectionPool) o2).getPoolProperties(); + + int activeConnections1 = ((ConnectionPool) o1).getActive(); + int activeConnections2 = ((ConnectionPool) o2).getActive(); + + return (props1.getMaxActive() - activeConnections1) - (props2.getMaxActive() - activeConnections2); + } + } + } + + /** + * Connection class holds client and related pool. + * + * @author Kuldeep.Mishra + * + */ + public class Connection + { + private Cassandra.Client client; + + private ConnectionPool pool; + + public Connection(org.apache.cassandra.thrift.Cassandra.Client client, ConnectionPool pool) + { + this.client = client; + this.pool = pool; + } + + public Cassandra.Client getClient() + { + return client; + } + + public ConnectionPool getPool() + { + return pool; + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataHandler.java new file mode 100644 index 000000000..d86aac6b3 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataHandler.java @@ -0,0 +1,124 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.SuperColumn; +import org.scale7.cassandra.pelops.Bytes; + +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.datahandler.CassandraDataHandlerBase; +import com.impetus.client.cassandra.thrift.ThriftClientFactory.Connection; +import com.impetus.kundera.db.DataRow; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Data handler for Thrift Clients + * + * @author amresh.singh + */ +/** + * @author vivek.mishra + * + */ +public final class ThriftDataHandler extends CassandraDataHandlerBase implements CassandraDataHandler +{ + private final ThriftClient thriftClient; + + public ThriftDataHandler(final ThriftClient thriftClient) + { + super(thriftClient); + this.thriftClient = thriftClient; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.cassandra.datahandler.CassandraDataHandlerBase# + * fromThriftRow(java.lang.Class, + * com.impetus.kundera.metadata.model.EntityMetadata, java.lang.String, + * java.util.List, boolean, org.apache.cassandra.thrift.ConsistencyLevel) + */ + @Override + public Object fromThriftRow(Class clazz, EntityMetadata m, Object rowKey, List relationNames, + boolean isWrapReq, ConsistencyLevel consistencyLevel) throws Exception + { + // List superColumnNames = m.getEmbeddedColumnFieldNames(); + + Object e = null; + SlicePredicate predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + + ByteBuffer key = ByteBuffer.wrap(PropertyAccessorHelper.toBytes(rowKey, m.getIdAttribute().getJavaType())); + Connection conn = thriftClient.getConection(); + try + { + List columnOrSuperColumns = conn.getClient().get_slice(key, new ColumnParent( + m.getTableName()), predicate, consistencyLevel); + + Map> thriftColumnOrSuperColumns = new HashMap>(); + thriftColumnOrSuperColumns.put(key, columnOrSuperColumns); + e = populateEntityFromSlice(m, relationNames, isWrapReq, e, thriftColumnOrSuperColumns); + } + finally + { + thriftClient.releaseConnection(conn); + } + return e; + } + + @Override + public E fromThriftRow(Class clazz, EntityMetadata m, DataRow tr) throws Exception + { + return super.fromThriftRow(clazz, m, tr); + } + + /** + * @param m + * @param relationNames + * @param isWrapReq + * @param e + * @param columnOrSuperColumnsFromRow + * @return + * @throws CharacterCodingException + */ + private Object populateEntityFromSlice(EntityMetadata m, List relationNames, boolean isWrapReq, Object e, + Map> columnOrSuperColumnsFromRow) throws CharacterCodingException + { + ThriftDataResultHelper dataGenerator = new ThriftDataResultHelper(); + for (ByteBuffer key : columnOrSuperColumnsFromRow.keySet()) + { + ThriftRow tr = new ThriftRow(); + tr.setColumnFamilyName(m.getTableName()); + tr.setId(PropertyAccessorHelper.getObject(m.getIdAttribute().getJavaType(), key.array())); + tr = dataGenerator.translateToThriftRow(columnOrSuperColumnsFromRow, m.isCounterColumnType(), m.getType(), + tr); + e = populateEntity(tr, m, relationNames, isWrapReq); + } + return e; + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataResultHelper.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataResultHelper.java new file mode 100644 index 000000000..38a1699ae --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftDataResultHelper.java @@ -0,0 +1,210 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.lang.reflect.Field; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.KeySlice; +import org.scale7.cassandra.pelops.Bytes; + +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.property.PropertyAccessor; +import com.impetus.kundera.property.PropertyAccessorFactory; + +/** + * Provides utility methods for extracting useful data from Thrift result + * retrieved from database (usually in the form of {@link ColumnOrSuperColumn} + * + * @author amresh.singh + */ +public class ThriftDataResultHelper +{ + public enum ColumnFamilyType + { + COLUMN, /* Column family */ + SUPER_COLUMN, /* Super Column family */ + COUNTER_COLUMN, /* Counter Column family */ + COUNTER_SUPER_COLUMN + /* Super Counter Column family */ + } + + /** + * Transforms data retrieved as result via thrift to a List whose content + * type is determined by {@link ColumnFamilyType} + */ + public static List transformThriftResult(List coscList, + ColumnFamilyType columnFamilyType, ThriftRow row) + { + List result = new ArrayList(coscList.size()); + for (ColumnOrSuperColumn cosc : coscList) + { + result.add(transformThriftResult(cosc, columnFamilyType, row)); + } + return result; + } + + public static T transformThriftResult(ColumnOrSuperColumn cosc, ColumnFamilyType columnFamilyType, ThriftRow row) + { + Object output = null; + if (cosc != null) + { + switch (columnFamilyType) + { + case COLUMN: + output = cosc.column; + if (row != null) + { + row.addColumn(cosc.column); + } + break; + + case SUPER_COLUMN: + output = cosc.super_column; + if (row != null) + { + row.addSuperColumn(cosc.super_column); + } + break; + + case COUNTER_COLUMN: + output = cosc.counter_column; + if (row != null) + { + row.addCounterColumn(cosc.counter_column); + } + break; + + case COUNTER_SUPER_COLUMN: + output = cosc.counter_super_column; + if (row != null) + { + row.addCounterSuperColumn(cosc.counter_super_column); + } + break; + } + } + return (T) output; + } + + /** + * Transforms data retrieved as result via thrift to a Map whose content + * type is determined by {@link ColumnFamilyType} + */ + public static Map> transformThriftResult( + Map> coscResultMap, ColumnFamilyType columnFamilyType, ThriftRow row) + { + + Map> output = new HashMap>(); + + for (ByteBuffer key : coscResultMap.keySet()) + { + output.put(key, (List) transformThriftResult(coscResultMap.get(key), columnFamilyType, row)); + } + + return output; + } + + public static Map> transformThriftResult(ColumnFamilyType columnFamilyType, + List keySlices, ThriftRow row) + { + + Map> output = new HashMap>(); + + for (KeySlice keySlice : keySlices) + { + output.put(Bytes.fromByteArray(keySlice.getKey()), + (List) transformThriftResult(keySlice.getColumns(), columnFamilyType, row)); + } + + return output; + } + + /** + * Transforms data retrieved as result via thrift to a List whose content + * type is determined by {@link ColumnFamilyType} + */ + public List transformThriftResultAndAddToList(Map> coscResultMap, + ColumnFamilyType columnFamilyType, ThriftRow row) + { + + List coscList = new ArrayList(); + + for (List list : coscResultMap.values()) + { + coscList.addAll(list); + } + + return transformThriftResult(coscList, columnFamilyType, row); + } + + /** + * Translates into thrift row. + * + * @param coscResultMap + * @param isCounterType + * @param columnFamilyType + * @param row + * @return + */ + public ThriftRow translateToThriftRow(Map> coscResultMap, + boolean isCounterType, Type columnFamilyType, ThriftRow row) + { + ColumnFamilyType columnType = ColumnFamilyType.COLUMN; + + if (isCounterType) + { + if (columnFamilyType.equals(Type.SUPER_COLUMN_FAMILY)) + { + columnType = ColumnFamilyType.COUNTER_SUPER_COLUMN; + } + else + { + columnType = ColumnFamilyType.COUNTER_COLUMN; + } + } + else if (columnFamilyType.equals(Type.SUPER_COLUMN_FAMILY)) + { + columnType = ColumnFamilyType.SUPER_COLUMN; + } + transformThriftResultAndAddToList(coscResultMap, columnType, row); + return row; + } + + /** + * Fetches Row keys from a {@link List} of {@link KeySlice} + */ + public static List getRowKeys(List keySlices, EntityMetadata metadata) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor((Field) metadata.getIdAttribute() + .getJavaMember()); + List rowKeys = new ArrayList(); + for (KeySlice keySlice : keySlices) + { + byte[] key = keySlice.getKey(); + Object rowKey = accessor.fromBytes(metadata.getIdAttribute().getJavaType(), key); + rowKeys.add(rowKey); + } + return rowKeys; + } + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftInvertedIndexHandler.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftInvertedIndexHandler.java new file mode 100644 index 000000000..6292937c6 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftInvertedIndexHandler.java @@ -0,0 +1,337 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ColumnPath; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexClause; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.SuperColumn; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraUtilities; +import com.impetus.client.cassandra.datahandler.CassandraDataHandler; +import com.impetus.client.cassandra.index.CassandraIndexHelper; +import com.impetus.client.cassandra.index.InvertedIndexHandler; +import com.impetus.client.cassandra.index.InvertedIndexHandlerBase; +import com.impetus.client.cassandra.thrift.ThriftClientFactory.Connection; +import com.impetus.client.cassandra.thrift.ThriftDataResultHelper.ColumnFamilyType; +import com.impetus.kundera.db.SearchResult; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.index.IndexingException; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Thrift implementation of {@link InvertedIndexHandler} + * + * @author amresh.singh + */ +public class ThriftInvertedIndexHandler extends InvertedIndexHandlerBase implements InvertedIndexHandler +{ + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(ThriftInvertedIndexHandler.class); + + private final ThriftClient thriftClient; + + public ThriftInvertedIndexHandler(final ThriftClient thriftClient, final boolean useSecondryIndex) + { + this.thriftClient = thriftClient; + this.useSecondryIndex = useSecondryIndex; + } + + @Override + public void write(Node node, EntityMetadata entityMetadata, String persistenceUnit, + ConsistencyLevel consistencyLevel, CassandraDataHandler cdHandler) + { + // Write to Inverted Index table if applicable + boolean invertedIndexingApplicable = CassandraIndexHelper.isInvertedIndexingApplicable(entityMetadata, useSecondryIndex); + + if (invertedIndexingApplicable) + { + String indexColumnFamily = CassandraIndexHelper.getInvertedIndexTableName(entityMetadata.getTableName()); + + ThriftDataHandler thriftDataHandler = (ThriftDataHandler) cdHandler; + + List indexThriftyRows = thriftDataHandler.toIndexThriftRow(node.getData(), entityMetadata, + indexColumnFamily); + Connection conn = thriftClient.getConection(); + try + { + String keyspace = CassandraUtilities.getKeyspace(persistenceUnit); + + for (ThriftRow thriftRow : indexThriftyRows) + { + byte[] rowKey = PropertyAccessorHelper.toBytes(thriftRow.getId(), thriftRow.getId().getClass()); + + // Create Insertion List + List insertion_list = new ArrayList(); + + List thriftColumns = thriftRow.getColumns(); + List thriftSuperColumns = thriftRow.getSuperColumns(); + if (thriftColumns != null && !thriftColumns.isEmpty()) + { + for (Column column : thriftColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setColumn(column)); + insertion_list.add(mut); + } + } + + if (thriftSuperColumns != null && !thriftSuperColumns.isEmpty()) + { + for (SuperColumn superColumn : thriftSuperColumns) + { + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setSuper_column(superColumn)); + insertion_list.add(mut); + } + } + + // Create Mutation Map + Map> columnFamilyValues = new HashMap>(); + columnFamilyValues.put(indexColumnFamily, insertion_list); + Map>> mulationMap = new HashMap>>(); + mulationMap.put(ByteBuffer.wrap(rowKey), columnFamilyValues); + + // Write Mutation map to database + conn.getClient().batch_mutate(mulationMap, consistencyLevel); + } + } + catch (IllegalStateException e) + { + log.error("Unable to insert records into inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (InvalidRequestException e) + { + log.error("Unable to insert records into inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TException e) + { + log.error("Unable to insert records into inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (UnavailableException e) + { + log.error("Unable to insert records into inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TimedOutException e) + { + log.error("Unable to insert records into inverted index, Caused by: .", e); + throw new IndexingException(e); + } + finally + { + thriftClient.releaseConnection(conn); + } + } + } + + @Override + public List search(EntityMetadata m, String persistenceUnit, ConsistencyLevel consistencyLevel, + Map> indexClauseMap) + { + + return super.search(m, persistenceUnit, consistencyLevel, indexClauseMap); + } + + @Override + protected void searchSuperColumnsInRange(String columnFamilyName, ConsistencyLevel consistencyLevel, + String persistenceUnit, String rowKey, byte[] searchSuperColumnName, List thriftSuperColumns, + byte[] start, byte[] finish) + { + SlicePredicate colPredicate = new SlicePredicate(); + SliceRange sliceRange = new SliceRange(); + sliceRange.setStart(start); + sliceRange.setFinish(finish); + colPredicate.setSlice_range(sliceRange); + Connection conn = thriftClient.getConection(); + + List coscList = null; + try + { + coscList = conn.getClient().get_slice(ByteBuffer.wrap(rowKey.getBytes()), + new ColumnParent(columnFamilyName), colPredicate, consistencyLevel); + } + catch (InvalidRequestException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (UnavailableException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TimedOutException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TException e) + { + log.error("Unable to search from inverted index, Caused by: ", e); + throw new IndexingException(e); + } + finally + { + thriftClient.releaseConnection(conn); + } + List allThriftSuperColumns = ThriftDataResultHelper.transformThriftResult(coscList, + ColumnFamilyType.SUPER_COLUMN, null); + + for (SuperColumn superColumn : allThriftSuperColumns) + { + if (superColumn == null) + continue; + + if (superColumn.getName() == searchSuperColumnName) + { + thriftSuperColumns.add(superColumn); + } + } + } + + @Override + protected SuperColumn getSuperColumnForRow(ConsistencyLevel consistencyLevel, String columnFamilyName, + String rowKey, byte[] superColumnName, String persistenceUnit) + { + ColumnPath cp = new ColumnPath(columnFamilyName); + cp.setSuper_column(superColumnName); + ColumnOrSuperColumn cosc = null; + Connection conn = thriftClient.getConection(); + + try + { + cosc = conn.getClient().get(ByteBuffer.wrap(rowKey.getBytes()), cp, consistencyLevel); + } + catch (InvalidRequestException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (NotFoundException e) + { + log.warn("Not found any record in inverted index table."); + } + catch (UnavailableException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TimedOutException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TException e) + { + log.error("Unable to search from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + finally + { + thriftClient.releaseConnection(conn); + } + SuperColumn thriftSuperColumn = ThriftDataResultHelper.transformThriftResult(cosc, + ColumnFamilyType.SUPER_COLUMN, null); + return thriftSuperColumn; + } + + @Override + public void delete(Object entity, EntityMetadata metadata, ConsistencyLevel consistencyLevel) + { + + super.delete(entity, metadata, consistencyLevel); + + } + + @Override + protected void deleteColumn(String indexColumnFamily, String rowKey, byte[] superColumnName, + String persistenceUnit, ConsistencyLevel consistencyLevel, byte[] columnName) + { + ColumnPath cp = new ColumnPath(indexColumnFamily); + cp.setSuper_column(superColumnName); + Connection conn = thriftClient.getConection(); + try + { + ColumnOrSuperColumn cosc; + try + { + cosc = conn.getClient().get(ByteBuffer.wrap(rowKey.getBytes()), cp, consistencyLevel); + } + catch (NotFoundException e) + { + return; + } + SuperColumn thriftSuperColumn = ThriftDataResultHelper.transformThriftResult(cosc, + ColumnFamilyType.SUPER_COLUMN, null); + + if (thriftSuperColumn != null && thriftSuperColumn.getColumns() != null + && thriftSuperColumn.getColumns().size() > 1) + { + cp.setColumn(columnName); + } + conn.getClient().remove(ByteBuffer.wrap(rowKey.getBytes()), cp, System.currentTimeMillis(), + consistencyLevel); + } + catch (InvalidRequestException e) + { + log.error("Unable to delete data from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (UnavailableException e) + { + log.error("Unable to delete data from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TimedOutException e) + { + log.error("Unable to delete data from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + catch (TException e) + { + log.error("Unable to delete data from inverted index, Caused by: .", e); + throw new IndexingException(e); + } + finally + { + thriftClient.releaseConnection(conn); + } + } +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftRow.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftRow.java new file mode 100644 index 000000000..91202915e --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/ThriftRow.java @@ -0,0 +1,246 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.cassandra.thrift; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.CounterColumn; +import org.apache.cassandra.thrift.CounterSuperColumn; +import org.apache.cassandra.thrift.SuperColumn; + +/** + * Utility class that represents a row in Cassandra DB. + * + * @author amresh.singh + */ +public class ThriftRow +{ + /** Id of the row. */ + private Object id; + + /** name of the family. */ + private String columnFamilyName; + + /** list of thrift columns from the row. */ + private List columns; + + /** list of thrift super columns columns from the row. */ + private List superColumns; + + /** list of thrift counter columns from the row. */ + private List counterColumns; + + /** list of thrift counter super columns columns from the row. */ + private List counterSuperColumns; + + /** + * default constructor. + */ + + public ThriftRow() + { + columns = new ArrayList(); + superColumns = new ArrayList(); + counterColumns = new ArrayList(); + counterSuperColumns = new ArrayList(); + } + + /** + * The Constructor. + * + * @param id + * the id + * @param columnFamilyName + * the column family name + * @param columns + * the columns + * @param superColumns + * the super columns + */ + public ThriftRow(Object id, String columnFamilyName, List columns, List superColumns, + List counterColumns, List counterSuperColumns) + { + this.id = id; + this.columnFamilyName = columnFamilyName; + if (columns != null) + { + this.columns = columns; + } + + if (superColumns != null) + { + this.superColumns = superColumns; + } + if (counterColumns != null) + { + this.counterColumns = counterColumns; + } + + if (counterSuperColumns != null) + { + this.counterSuperColumns = counterSuperColumns; + } + } + + /** + * Adds the column. + * + * @param column + * the column + */ + public void addColumn(Column column) + { + columns.add(column); + } + + /** + * @return the id + */ + public Object getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Object id) + { + this.id = id; + } + + /** + * @return the columnFamilyName + */ + public String getColumnFamilyName() + { + return columnFamilyName; + } + + /** + * @param columnFamilyName + * the columnFamilyName to set + */ + public void setColumnFamilyName(String columnFamilyName) + { + this.columnFamilyName = columnFamilyName; + } + + /** + * @return the columns + */ + public List getColumns() + { + return columns; + } + + /** + * @param columns + * the columns to set + */ + public void setColumns(List columns) + { + this.columns = columns; + } + + /** + * @return the superColumns + */ + public List getSuperColumns() + { + return superColumns; + } + + /** + * @param superColumns + * the superColumns to set + */ + public void setSuperColumns(List superColumns) + { + this.superColumns = superColumns; + } + + /** + * Adds the super column. + * + * @param superColumn + * the super column + */ + public void addSuperColumn(SuperColumn superColumn) + { + this.superColumns.add(superColumn); + } + + /** + * @return the counterColumns + */ + public List getCounterColumns() + { + return counterColumns; + } + + /** + * @param counterColumns + * the counterColumns to set + */ + public void setCounterColumns(List counterColumns) + { + this.counterColumns = counterColumns; + } + + /** + * Adds the counter column. + * + * @param counter + * column the column + */ + public void addCounterColumn(CounterColumn column) + { + counterColumns.add(column); + } + + /** + * @return the counterSuperColumns + */ + public List getCounterSuperColumns() + { + return counterSuperColumns; + } + + /** + * @param counterSuperColumns + * the counterSuperColumns to set + */ + public void setCounterSuperColumns(List counterSuperColumns) + { + this.counterSuperColumns = counterSuperColumns; + } + + /** + * Adds the counter super column. + * + * @param countersuperColumn + * the super column + */ + public void addCounterSuperColumn(CounterSuperColumn superColumn) + { + this.counterSuperColumns.add(superColumn); + } + +} diff --git a/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/TranslationException.java b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/TranslationException.java new file mode 100644 index 000000000..30127b4a5 --- /dev/null +++ b/src/kundera-cassandra/src/main/java/com/impetus/client/cassandra/thrift/TranslationException.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift; + +import com.impetus.kundera.KunderaException; + +/** + * Runtime exception class for CQL translation. + * + * @author vivek.mishra + * + */ +public class TranslationException extends KunderaException +{ + /** + * + */ + private static final long serialVersionUID = 2557677206649004876L; + + /** + * + */ + public TranslationException() + { + } + + /** + * @param arg0 + */ + public TranslationException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public TranslationException(Throwable arg0) + { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public TranslationException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + +} diff --git a/src/kundera-cassandra/src/main/resources/log4j-server.properties b/src/kundera-cassandra/src/main/resources/log4j-server.properties new file mode 100644 index 000000000..a394f0930 --- /dev/null +++ b/src/kundera-cassandra/src/main/resources/log4j-server.properties @@ -0,0 +1,29 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +log4j.rootLogger=WARN, DRFA, CONSOLE + +# rolling log file ("system.log +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.DatePattern='.'yyyy-MM-dd-HH +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +log4j.appender.DRFA.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n +log4j.appender.DRFA.File=${user.home}/kundera.log + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n \ No newline at end of file diff --git a/src/kundera-cassandra/src/main/resources/solandra.properties b/src/kundera-cassandra/src/main/resources/solandra.properties new file mode 100644 index 000000000..ccfefa82a --- /dev/null +++ b/src/kundera-cassandra/src/main/resources/solandra.properties @@ -0,0 +1,46 @@ + +#Set to true if you want solandra to compress fields + meta data +#This will size on disk at the cost of indexing speed +#Compression is google snappy +solandra.compression = false + +#The consistency level of solandra reads and writes +solandra.consistency = ONE + +#The number of milliseconds solandra will wait before +#checking to see if it's cache needs to be invalidated +#for a given index +solandra.cache.invalidation.check.interval = 1000 + +#The largest number of documents to store in one sub-index +# +#Solandra splits a index into sub-indexes in order to search them in parallel +#across nodes. +# +#*NOTE* This value should not be changed once documents are indexed +#*NOTE* This value must be a power of 2 +solandra.maximum.docs.per.shard = 131072 + +#The number of index ids to reserve at a time +#*NOTE* this value must be a power of 2 +solandra.index.id.reserve.size = 16384 + +#The number of shards to write to at once +#This should roughly equal the number of +#nodes in your cluster +solandra.shards.at.once = 4 + +#The number of documents to buffer per index +#before forcing a commit. +solandra.write.buffer.queue.size = 16 + +#keyspace name for solandra +solandra.keyspace = L + +#The number of retries solandra will attempt before +#failing a write or read (TimeoutException) +cassandra.retries = 1024 + +#The number of milliseconds solandra will wait before +#retrying a read or write +cassandra.retries.sleep = 100 diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultSuperUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultSuperUser.java new file mode 100644 index 000000000..db2ecbf6f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultSuperUser.java @@ -0,0 +1,92 @@ +package com.impetus.client.cassandra.config; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.client.twitter.entities.PersonalDetailCassandra; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "CassandraDefaultSuperUser", schema = "KunderaCassandraXmlTest@CassandraXmlPropertyTest") +public class CassandraDefaultSuperUser +{ + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + @Embedded + private PersonalDetailCassandra personalDetailCassandra; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + + public PersonalDetailCassandra getPersonalDetailCassandra() + { + return personalDetailCassandra; + } + + public void setPersonalDetailCassandra(PersonalDetailCassandra personalDetailCassandra) + { + this.personalDetailCassandra = personalDetailCassandra; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultUser.java new file mode 100644 index 000000000..d6c535f64 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraDefaultUser.java @@ -0,0 +1,80 @@ +/** + * + */ +package com.impetus.client.cassandra.config; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "CassandraDefaultUser", schema = "KunderaCassandraXmlTest@CassandraXmlPropertyTest") +public class CassandraDefaultUser +{ + + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSchemaGenerationUsingXmlTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSchemaGenerationUsingXmlTest.java new file mode 100644 index 000000000..622b9c9e5 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSchemaGenerationUsingXmlTest.java @@ -0,0 +1,158 @@ +/** + * + */ +package com.impetus.client.cassandra.config; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.db.marshal.BytesType; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * @author Kuldeep Mishra + * + */ +public class CassandraSchemaGenerationUsingXmlTest +{ + private EntityManagerFactory emf; + + private String keyspaceName = "KunderaCassandraXmlTest"; + + private Logger logger = LoggerFactory.getLogger(CassandraSchemaGenerationUsingXmlTest.class); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(keyspaceName); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + emf = Persistence.createEntityManagerFactory("CassandraXmlPropertyTest", propertyMap); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + CassandraCli.dropKeySpace(keyspaceName); + } + + @Test + public void test() + { + try + { + KsDef ksDef = CassandraCli.client.describe_keyspace(keyspaceName); + + Assert.assertNotNull(ksDef); + Assert.assertEquals(keyspaceName, ksDef.getName()); + Assert.assertEquals(SimpleStrategy.class.getName(), ksDef.getStrategy_class()); + Assert.assertEquals("1", ksDef.getStrategy_options().get("replication_factor")); + Assert.assertTrue(ksDef.isDurable_writes()); + Assert.assertNotNull(ksDef.getCf_defs()); + Assert.assertNotNull(ksDef.getStrategy_options()); + Assert.assertEquals(5, ksDef.getCf_defsSize()); + + for (CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertNotNull(cfDef); + if ("CASSANDRAUSERXYZ".equals(cfDef.getName())) + { + Assert.assertEquals("CASSANDRAUSERXYZ", cfDef.getName()); + Assert.assertEquals(keyspaceName, cfDef.getKeyspace()); + Assert.assertEquals("Standard", cfDef.getColumn_type()); + Assert.assertFalse(cfDef.getComment().isEmpty()); + Assert.assertEquals(UTF8Type.class.getName(), cfDef.getComparator_type()); + Assert.assertNull(cfDef.getSubcomparator_type()); + Assert.assertEquals(2, cfDef.getColumn_metadataSize()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getDefault_validation_class()); + Assert.assertTrue(cfDef.isReplicate_on_write()); + Assert.assertEquals(16, cfDef.getMin_compaction_threshold()); + Assert.assertEquals(64, cfDef.getMax_compaction_threshold()); + } + else if ("CassandraDefaultUser".equals(cfDef.getName())) + { + Assert.assertEquals(keyspaceName, cfDef.getKeyspace()); + Assert.assertEquals("Standard", cfDef.getColumn_type()); + Assert.assertTrue(cfDef.getComment().isEmpty()); + Assert.assertEquals(UTF8Type.class.getName(), cfDef.getComparator_type()); + Assert.assertNull(cfDef.getSubcomparator_type()); + Assert.assertEquals(2, cfDef.getColumn_metadataSize()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getDefault_validation_class()); + Assert.assertTrue(cfDef.isReplicate_on_write()); + Assert.assertEquals(4, cfDef.getMin_compaction_threshold()); + Assert.assertEquals(32, cfDef.getMax_compaction_threshold()); + } + else if ("CassandraDefaultSuperUser".equals(cfDef.getName())) + { + Assert.assertEquals(keyspaceName, cfDef.getKeyspace()); + Assert.assertEquals("Super", cfDef.getColumn_type()); + Assert.assertTrue(cfDef.getComment().isEmpty()); + Assert.assertEquals(UTF8Type.class.getName(), cfDef.getComparator_type()); + Assert.assertNotNull(cfDef.getSubcomparator_type()); + Assert.assertEquals(UTF8Type.class.getName(), cfDef.getSubcomparator_type()); + Assert.assertEquals(0, cfDef.getColumn_metadataSize()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getDefault_validation_class()); + } + else if ("CASSANDRASUPERUSER".equals(cfDef.getName())) + { + Assert.assertEquals("CASSANDRASUPERUSER", cfDef.getName()); + Assert.assertEquals(keyspaceName, cfDef.getKeyspace()); + Assert.assertEquals("Super", cfDef.getColumn_type()); + Assert.assertFalse(cfDef.getComment().isEmpty()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getComparator_type()); + Assert.assertNotNull(cfDef.getSubcomparator_type()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getSubcomparator_type()); + Assert.assertEquals(0, cfDef.getColumn_metadataSize()); + Assert.assertEquals(BytesType.class.getName(), cfDef.getDefault_validation_class()); + } + else + { + + } + } + + } + catch (NotFoundException nfe) + { + Assert.fail(); + logger.error("Error in test, Caused by: .",nfe.getMessage()); + } + catch (InvalidRequestException ire) + { + Assert.fail(); + logger.error("Error in test, Caused by: .",ire.getMessage()); + } + catch (TException te) + { + Assert.fail(); + logger.error("Error in test, caused by: .",te.getMessage()); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSuperUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSuperUser.java new file mode 100644 index 000000000..3e43d286f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraSuperUser.java @@ -0,0 +1,92 @@ +package com.impetus.client.cassandra.config; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.client.twitter.entities.PersonalDetailCassandra; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "CASSANDRASUPERUSER", schema = "KunderaCassandraXmlTest@CassandraXmlPropertyTest") +public class CassandraSuperUser +{ + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + @Embedded + private PersonalDetailCassandra personalDetailCassandra; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + + public PersonalDetailCassandra getPersonalDetailCassandra() + { + return personalDetailCassandra; + } + + public void setPersonalDetailCassandra(PersonalDetailCassandra personalDetailCassandra) + { + this.personalDetailCassandra = personalDetailCassandra; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUser.java new file mode 100644 index 000000000..d6c7c01c3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUser.java @@ -0,0 +1,80 @@ +/** + * + */ +package com.impetus.client.cassandra.config; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "CASSANDRAUSERXYZ", schema = "KunderaCassandraXmlTest@CassandraXmlPropertyTest") +public class CassandraUser +{ + + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUserTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUserTest.java new file mode 100644 index 000000000..d59549141 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/config/CassandraUserTest.java @@ -0,0 +1,92 @@ +/** + * + */ +package com.impetus.client.cassandra.config; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * @author Kuldeep Mishra + * + */ +public class CassandraUserTest +{ + + /** + * + */ + private static final String _PU = "CassandraXmlPropertyTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + private Map puProperties = new HashMap(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + puProperties.put("kundera.ddl.auto.prepare", "create-drop"); + puProperties.put("kundera.keyspace", "KunderaKeyspace"); + puProperties.put("kundera.client.lookup.class", "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + puProperties.put("kundera.nodes", "localhost"); + puProperties.put("kundera.port", "9160"); + puProperties.put("kundera.client.property", "kunderaTest.xml"); + puProperties.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + emf = Persistence.createEntityManagerFactory(_PU, puProperties); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + puProperties = null; + CassandraCli.dropKeySpace("KunderaKeyspace"); + } + + @Test + public void test() + { + CassandraUser u = new CassandraUser(); + u.setName("kuldeep"); + u.setAge(24); + u.setAddress("gzb"); + em.persist(u); + + em.clear(); + + CassandraUser user = em.find(CassandraUser.class, "kuldeep"); + Assert.assertNotNull(user); + Assert.assertEquals(24, user.getAge()); + Assert.assertEquals("gzb", user.getAddress()); + + Query q = em.createQuery("Select u from CassandraUser u"); + List users = q.getResultList(); + Assert.assertNotNull(users); + Assert.assertEquals(1, users.size()); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressHandler.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressHandler.java new file mode 100644 index 000000000..4939d0bd9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressHandler.java @@ -0,0 +1,20 @@ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.PostPersist; +import javax.persistence.PrePersist; + +public class AddressHandler +{ + + @PrePersist + public void handledPrePersist(AddressListenerDTO address) + { + address.setStreet("aaaa"); + } + + @PostPersist + public void handledPostPersist(AddressListenerDTO address) + { + address.setStreet("bbbb"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressListenerDTO.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressListenerDTO.java new file mode 100644 index 000000000..797fa5ab1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/AddressListenerDTO.java @@ -0,0 +1,40 @@ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "address", schema = "KunderaExamples@secIdxCassandraTest") +@EntityListeners({ AddressHandler.class }) +public class AddressListenerDTO +{ + @Id + private String addressId; + + @Column + private String street; + + public String getAddressId() + { + return addressId; + } + + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/CompositeTypeRunner.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/CompositeTypeRunner.java new file mode 100644 index 000000000..ab17f7736 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/CompositeTypeRunner.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.CompositeType; +import org.apache.cassandra.db.marshal.CompositeType.Builder; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ColumnPath; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.CqlResult; +import org.apache.cassandra.thrift.CqlRow; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.apache.cassandra.thrift.TBinaryProtocol; +import org.apache.thrift.transport.TFramedTransport; +import org.apache.thrift.transport.TSocket; +import org.scale7.cassandra.pelops.Bytes; + +/** + * @author vivek.mishra + * + */ +public class CompositeTypeRunner +{ + public static void main(String[] args) throws Exception + { + + TSocket socket = new TSocket("localhost", 9160); + TFramedTransport transport = new TFramedTransport(socket); + + Cassandra.Client client = new Cassandra.Client(new TBinaryProtocol(transport)); + transport.open(); + client.set_cql_version("3.0.0"); + List cfDefs = new ArrayList(); + + /* + * CfDef cfDef = new CfDef(); cfDef.setName("test"); cfDef.keyspace = + * "bigdata"; cfDef.setComparator_type("UTF8Type"); + * cfDef.setDefault_validation_class("UTF8Type"); // + * cfDef.setKey_validation_class("UTF8Type"); + * + * cfDefs.add(cfDef); + */ + + KsDef ksDef = new KsDef("bigdata", SimpleStrategy.class.getName(), cfDefs); + + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + + ksDef.strategy_options.put("replication_factor", "1"); + client.system_add_keyspace(ksDef); + client.set_keyspace("bigdata"); + + String cql_Query = "create columnfamily test1 (name text, age text, address text, PRIMARY KEY(name,age))"; + + client.execute_cql_query(ByteBuffer.wrap(("USE bigdata").getBytes("UTF-8")), Compression.NONE); + + client.execute_cql_query(ByteBuffer.wrap((cql_Query).getBytes("UTF-8")), Compression.NONE); + + /* + * ColumnParent parent = new ColumnParent("test1"); + * + * List> keyTypes = new ArrayList>(); + * keyTypes.add(UTF8Type.instance); keyTypes.add(UTF8Type.instance); + * CompositeType compositeKey = CompositeType.getInstance(keyTypes); + * + * Builder builder = new Builder(compositeKey); + * builder.add(ByteBuffer.wrap("1".getBytes())); + * builder.add(ByteBuffer.wrap("2".getBytes())); ByteBuffer rowid = + * builder.build(); + * + * Column column = new Column(); column.setName("value".getBytes()); + * column.setValue("aaa".getBytes()); + * column.setTimestamp(System.currentTimeMillis()); + * + * client.insert(rowid, parent, column, ConsistencyLevel.ONE); + */ + + ColumnParent parent = new ColumnParent("test1"); + + List> keyTypes = new ArrayList>(); + keyTypes.add(UTF8Type.instance); + keyTypes.add(UTF8Type.instance); + CompositeType compositeKey = CompositeType.getInstance(keyTypes); + + Builder builder = new Builder(compositeKey); + builder.add(ByteBuffer.wrap("3".getBytes())); + builder.add(ByteBuffer.wrap("address".getBytes())); + ByteBuffer columnName = builder.build(); + + Column column = new Column(); + column.setName(columnName); + column.setValue("4".getBytes()); + column.setTimestamp(System.currentTimeMillis()); + + client.insert(ByteBuffer.wrap("1".getBytes()), parent, column, ConsistencyLevel.ONE); + + SlicePredicate slicePredicate = new SlicePredicate(); + slicePredicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + List columns = client.get_slice(ByteBuffer.wrap("1".getBytes()), parent, slicePredicate, + ConsistencyLevel.ONE); + + for (ColumnOrSuperColumn col : columns) + { + if (col.column != null) + { + System.out.println(new String(col.getColumn().getName())); // Printing + // "EMPTY" + // String! + System.out.println(new String(col.getColumn().getValue())); + } + else if (col.super_column != null) + { + + } + else if (col.counter_column != null) + { + + } + else if (col.counter_super_column != null) + { + + } + } + + // On cql select query. + + String selectQuery = "Select * from test1"; + CqlResult result = client.execute_cql_query(ByteBuffer.wrap(selectQuery.getBytes("UTF-8")), Compression.NONE); + Iterator rows = result.getRowsIterator(); + while (rows.hasNext()) + { + CqlRow row = rows.next(); + List cols = row.getColumns(); + for (Column c : cols) + { + System.out.println(new String(c.getName()) + "=>" + new String(c.getValue())); + + } + } + + ColumnPath path = new ColumnPath("test1"); + client.remove(ByteBuffer.wrap("1".getBytes()), path, System.currentTimeMillis(), ConsistencyLevel.ONE); + + // Insert after delete is not working for compound primary key? + + client.insert(ByteBuffer.wrap("1".getBytes()), parent, column, ConsistencyLevel.ONE); + + client.insert(ByteBuffer.wrap("2".getBytes()), parent, column, ConsistencyLevel.ONE); + + // while(result.) + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonHandler.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonHandler.java new file mode 100644 index 000000000..f5493b58c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonHandler.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.PostPersist; +import javax.persistence.PrePersist; + +public class PersonHandler +{ + + @PrePersist + public void handledPrePersist(PersonnelListenerDTO user) + { + user.setFirstName("kuldeep"); + } + + @PostPersist + public void handledPostPersist(PersonnelListenerDTO user) + { + user.setFirstName("vivek"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentity.java new file mode 100644 index 000000000..f967c8a89 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentity.java @@ -0,0 +1,69 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * @author impadmin + * + */ +@Entity +@Table(name = "PERSONIDENTITY", schema = "CompositeCassandra@composite_pu") +public class PersonIdentity +{ + @Id + private String personId; + + @Column + private String personName; + + @OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER) + @JoinColumn(name = "personId") + private List phones; + + + + public String getPersonName() + { + return personName; + } + + public void setPersonName(String personName) + { + this.personName = personName; + } + + + public String getPersonId() + { + return personId; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public List getPhones() + { + return phones; + } + + public void setPhones(List phones) + { + this.phones = phones; + } + + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentityTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentityTest.java new file mode 100644 index 000000000..3ac7fbfef --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonIdentityTest.java @@ -0,0 +1,108 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * @author impadmin + * + */ +public class PersonIdentityTest +{ + + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("CompositeCassandra"); + emf = Persistence.createEntityManagerFactory("composite_pu"); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("CompositeCassandra"); + em.close(); + emf.close(); + } + + @Test + public void test() + { + PhoneId phoneId1 = new PhoneId(); + phoneId1.setPhoneId("A"); + PhoneId phoneId2 = new PhoneId(); + phoneId2.setPhoneId("B"); + + Phone phone1 = new Phone(); + phone1.setPhoneId(phoneId1); + phone1.setPhoneNumber(99533533434l); + + Phone phone2 = new Phone(); + phone2.setPhoneId(phoneId2); + phone2.setPhoneNumber(9972723678l); + + List phones = new ArrayList(); + phones.add(phone1); + phones.add(phone2); + + PersonIdentity identity = new PersonIdentity(); + identity.setPersonId("1"); + identity.setPersonName("KK"); + identity.setPhones(phones); + + em.persist(identity); + + em.clear(); + + PersonIdentity foundPerson = em.find(PersonIdentity.class, "1"); + + Assert.assertNotNull(foundPerson); + Assert.assertNotNull(foundPerson.getPhones()); + Assert.assertFalse(foundPerson.getPhones().isEmpty()); + Assert.assertEquals(2,foundPerson.getPhones().size()); + Assert.assertNotNull(foundPerson.getPhones().get(0)); + Assert.assertNotNull(foundPerson.getPhones().get(1)); + Assert.assertNotNull(foundPerson.getPhones().get(0).getPhoneId()); + Assert.assertNotNull(foundPerson.getPhones().get(1).getPhoneId()); + + Assert.assertEquals(new Long(99533533434l), foundPerson.getPhones().get(0).getPhoneNumber()); + Assert.assertEquals(new Long(9972723678l), foundPerson.getPhones().get(1).getPhoneNumber()); + + Assert.assertEquals("1", foundPerson.getPhones().get(0).getPhoneId().getPersonId()); + + List phoneIds = new ArrayList(); + phoneIds.add("A"); + phoneIds.add("B"); + Assert.assertTrue(phoneIds.contains(foundPerson.getPhones().get(0).getPhoneId().getPhoneId())); + Assert.assertEquals("1", foundPerson.getPhones().get(1).getPhoneId().getPersonId()); + Assert.assertNotSame(foundPerson.getPhones().get(0).getPhoneId().getPhoneId(), foundPerson.getPhones().get(1).getPhoneId().getPhoneId()); + + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTO.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTO.java new file mode 100644 index 000000000..e32fe31d6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTO.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class PersonnelDTO. + * + * @author amresh.singh + */ + +@Entity +@Table(name = "person", schema = "KunderaExamples@secIdxCassandraTest") +@EntityListeners({ PersonHandler.class }) +public class PersonnelListenerDTO +{ + + /** The person id. */ + @Id + private String personId; + + /** The first name. */ + @Column(name = "first_name") + private String firstName; + + /** The last name. */ + @Column(name = "last_name") + private String lastName; + + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "personId") + private AddressListenerDTO address; + + /** + * Instantiates a new personnel dto. + * + * @param personId + * the person id + * @param firstName + * the first name + * @param lastName + * the last name + */ + public PersonnelListenerDTO(String personId, String firstName, String lastName) + { + this.personId = personId; + this.firstName = firstName; + this.lastName = lastName; + } + + /** + * Instantiates a new personnel dto. + */ + public PersonnelListenerDTO() + { + + } + + /** + * Gets the person id. + * + * @return the personId + */ + public String getPersonId() + { + return personId; + } + + /** + * Sets the person id. + * + * @param personId + * the personId to set + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the first name. + * + * @return the firstName + */ + public String getFirstName() + { + return firstName; + } + + /** + * Sets the first name. + * + * @param firstName + * the firstName to set + */ + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + /** + * Gets the last name. + * + * @return the lastName + */ + public String getLastName() + { + return lastName; + } + + /** + * Sets the last name. + * + * @param lastName + * the lastName to set + */ + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public AddressListenerDTO getAddress() + { + return address; + } + + public void setAddress(AddressListenerDTO address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTOTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTOTest.java new file mode 100644 index 000000000..c119484b2 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PersonnelListenerDTOTest.java @@ -0,0 +1,79 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; + +/** + * @author impadmin + * + */ +public class PersonnelListenerDTOTest +{ + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + Map propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + emf = Persistence.createEntityManagerFactory("secIdxCassandraTest", propertyMap); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + @Test + public void test() + { + AddressListenerDTO address = new AddressListenerDTO(); + address.setStreet("New Street"); + address.setAddressId("a1"); + PersonnelListenerDTO personnel = new PersonnelListenerDTO(); + personnel.setPersonId("1"); + personnel.setFirstName("kk"); + personnel.setLastName("Mishra"); + personnel.setAddress(address); + + em.persist(personnel); + + em.clear(); + + PersonnelListenerDTO foundPersonnel = em.find(PersonnelListenerDTO.class, "1"); + Assert.assertNotNull(foundPersonnel); + Assert.assertEquals("kuldeep", foundPersonnel.getFirstName()); + Assert.assertNotNull(foundPersonnel.getAddress()); + Assert.assertEquals("aaaa", foundPersonnel.getAddress().getStreet()); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/Phone.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/Phone.java new file mode 100644 index 000000000..259042e97 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/Phone.java @@ -0,0 +1,38 @@ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +@Entity +@Table(name = "PHONE", schema = "CompositeCassandra@composite_pu") +public class Phone +{ + @EmbeddedId + private PhoneId phoneIdentifier; + + @Column + private Long phoneNumber; + + public PhoneId getPhoneId() + { + return phoneIdentifier; + } + + public void setPhoneId(PhoneId phoneId) + { + this.phoneIdentifier = phoneId; + } + + public Long getPhoneNumber() + { + return phoneNumber; + } + + public void setPhoneNumber(Long phoneNumber) + { + this.phoneNumber = phoneNumber; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PhoneId.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PhoneId.java new file mode 100644 index 000000000..78d7bea1e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/PhoneId.java @@ -0,0 +1,36 @@ +package com.impetus.client.cassandra.thrift; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class PhoneId +{ + + @Column + private String personId; + + @Column + private String phoneId; + + public String getPersonId() + { + return personId; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public String getPhoneId() + { + return phoneId; + } + + public void setPhoneId(String phoneId) + { + this.phoneId = phoneId; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/ThriftClientTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/ThriftClientTest.java new file mode 100644 index 000000000..d9896a6f0 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/ThriftClientTest.java @@ -0,0 +1,200 @@ +package com.impetus.client.cassandra.thrift; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.thrift.entities.PersonMToM; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.persistence.context.jointable.JoinTableData.OPERATION; + +public class ThriftClientTest +{ + private String persistenceUnit = "thriftClientTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + private ThriftClient client; + + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + createSchema(); + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + client = (ThriftClient) clients.get(persistenceUnit); + } + + @After + public void tearDown() throws Exception + { + if (em != null) + { + em.close(); + } + if (emf != null) + { + emf.close(); + } + CassandraCli.dropKeySpace("KunderaExamples"); + } + + @Test + public void executeTests() + { + persistJoinTable(); + getColumnsById(); + findIdsByColumn(); + } + + private void persistJoinTable() + { + JoinTableData joinTableData = new JoinTableData(OPERATION.INSERT, "KunderaExamples", "PERSON_ADDRESS", + "PERSON_ID", "ADDRESS_ID", PersonMToM.class); + + Set values1 = new HashSet(); + values1.add("A"); + values1.add("B"); + Set values2 = new HashSet(); + values2.add("C"); + values2.add("D"); + + joinTableData.addJoinTableRecord("1", values1); + joinTableData.addJoinTableRecord("2", values2); + + client.persistJoinTable(joinTableData); + + } + + private void getColumnsById() + { + List columns1 = client.getColumnsById("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "1", + String.class); + Assert.assertNotNull(columns1); + Assert.assertFalse(columns1.isEmpty()); + Assert.assertEquals(2, columns1.size()); + Assert.assertTrue(columns1.contains("A")); + Assert.assertTrue(columns1.contains("B")); + + List columns2 = client.getColumnsById("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "2", + String.class); + Assert.assertNotNull(columns2); + Assert.assertFalse(columns2.isEmpty()); + Assert.assertEquals(2, columns2.size()); + Assert.assertTrue(columns2.contains("C")); + Assert.assertTrue(columns2.contains("D")); + + } + + private void findIdsByColumn() + { + Object[] ids1 = client.findIdsByColumn("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "A", + PersonMToM.class); + Assert.assertNotNull(ids1); + Assert.assertTrue(ids1.length == 1); + Assert.assertEquals("1", ids1[0]); + + Object[] ids2 = client.findIdsByColumn("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "B", + PersonMToM.class); + Assert.assertNotNull(ids2); + Assert.assertTrue(ids2.length == 1); + Assert.assertEquals("1", ids2[0]); + + Object[] ids3 = client.findIdsByColumn("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "C", + PersonMToM.class); + Assert.assertNotNull(ids3); + Assert.assertTrue(ids3.length == 1); + Assert.assertEquals("2", ids3[0]); + + Object[] ids4 = client.findIdsByColumn("KunderaExamples", "PERSON_ADDRESS", "PERSON_ID", "ADDRESS_ID", "D", + PersonMToM.class); + Assert.assertNotNull(ids4); + Assert.assertTrue(ids4.length == 1); + Assert.assertEquals("2", ids4[0]); + } + + private void createSchema() throws InvalidRequestException, SchemaDisagreementException, TException + { + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSON_ADDRESS"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_ID".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("ADDRESS_ID".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON")) + { + + CassandraCli.client.system_drop_column_family("PERSON"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUser.java new file mode 100644 index 000000000..d00cba145 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUser.java @@ -0,0 +1,81 @@ +package com.impetus.client.cassandra.thrift.cql; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "CQLUSER", schema = "CqlKeyspace@cassandra_cql") +@IndexCollection(columns = { @Index(name = "name"), @Index(name = "age") }) +public class CQLUser +{ + @Id + private int id; + + @Column + private String name; + + @Column + private int age; + + @Column + private transient int salary; + + @Column + private static String address; + + public int getId() + { + return id; + } + + public void setId(int id) + { + this.id = id; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public int getAge() + { + return age; + } + + public void setAge(int age) + { + this.age = age; + } + + public int getSalary() + { + return salary; + } + + public void setSalary(int salary) + { + this.salary = salary; + } + + public static String getAddress() + { + return address; + } + + public static void setAddress(String address) + { + CQLUser.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUserTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUserTest.java new file mode 100644 index 000000000..bf940e4c0 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CQLUserTest.java @@ -0,0 +1,95 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * @author Kuldeep + * + */ +public class CQLUserTest +{ + + private EntityManagerFactory emf; + + private String persistenceUnit = "cassandra_cql"; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + emf = Persistence.createEntityManagerFactory(persistenceUnit, propertyMap); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + emf = null; + } + + @Test + public void testCRUD() + { + EntityManager em = emf.createEntityManager(); + CQLUser user = new CQLUser(); + user.setId(1); + user.setName("Kuldeep"); + user.setAge(24); + + em.persist(user); + + em.clear(); + + CQLUser foundUser = em.find(CQLUser.class, 1); + Assert.assertNotNull(foundUser); + Assert.assertEquals(1, foundUser.getId()); + Assert.assertEquals(24, foundUser.getAge()); + Assert.assertEquals("Kuldeep", foundUser.getName()); + + foundUser.setName("KK"); + + em.merge(foundUser); + + em.clear(); + + CQLUser mergedUser = em.find(CQLUser.class, 1); + Assert.assertNotNull(mergedUser); + Assert.assertEquals(1, mergedUser.getId()); + Assert.assertEquals(24, mergedUser.getAge()); + Assert.assertEquals("KK", mergedUser.getName()); + + em.remove(mergedUser); + + CQLUser deletedUser = em.find(CQLUser.class, 1); + Assert.assertNull(deletedUser); + + em.clear(); + + deletedUser = em.find(CQLUser.class, 1); + Assert.assertNull(deletedUser); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CassandraBatchProcessorCQLTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CassandraBatchProcessorCQLTest.java new file mode 100644 index 000000000..51fc057b8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CassandraBatchProcessorCQLTest.java @@ -0,0 +1,49 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.batch.CassandraBatchProcessorTest; +import com.impetus.kundera.PersistenceProperties; + +/** + * @author impadmin + * + */ +public class CassandraBatchProcessorCQLTest extends CassandraBatchProcessorTest +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.client.crud.batch.CassandraBatchProcessorTest#setUp() + */ + @Before + public void setUp() throws Exception + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + propertyMap.put("kundera.batch.size", "5"); + AUTO_MANAGE_SCHEMA = false; + USE_CQL = false; + super.setUp(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.crud.batch.CassandraBatchProcessorTest#tearDown() + */ + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CountersTestOnCql.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CountersTestOnCql.java new file mode 100644 index 000000000..c9965c87d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/CountersTestOnCql.java @@ -0,0 +1,26 @@ +package com.impetus.client.cassandra.thrift.cql; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.countercolumns.CountersTest; +import com.impetus.kundera.PersistenceProperties; + +public class CountersTestOnCql extends CountersTest +{ + + @Before + public void setUp() throws Exception + { + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfiguration.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfiguration.java new file mode 100644 index 000000000..04735ff5e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfiguration.java @@ -0,0 +1,83 @@ +package com.impetus.client.cassandra.thrift.cql; + +import java.sql.Timestamp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "LoggingConfiguration", schema = "KunderaExamples@twissandraTest") +@IndexCollection(columns = { @Index(name = "logname") }) +public class LoggingConfiguration +{ + @Id + private String id; + + @Column + private String label; + + @Column + private String logname; + + @Column + private Timestamp nnow; + + @Column + private String lvl; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getLable() + { + return label; + } + + public void setLable(String lable) + { + this.label = lable; + } + + public String getLongName() + { + return logname; + } + + public void setLongName(String longName) + { + this.logname = longName; + } + + public String getLvl() + { + return lvl; + } + + public void setLvl(String lvl) + { + this.lvl = lvl; + } + + public Timestamp getNnow() + { + return nnow; + } + + public void setNnow(Timestamp nnow) + { + this.nnow = nnow; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfigurationTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfigurationTest.java new file mode 100644 index 000000000..ca3ecaf0b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/LoggingConfigurationTest.java @@ -0,0 +1,148 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; + +/** + * @author impadmin + * + */ +public class LoggingConfigurationTest +{ + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + emf = Persistence.createEntityManagerFactory("twissandraTest", propertyMap); + em = emf.createEntityManager(); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + } + + @Test + public void test() + { + LoggingConfiguration lc = new LoggingConfiguration(); + lc.setId("lc1"); + lc.setLable("one"); + lc.setLongName("first lc"); + + LoggingConfiguration lc1 = new LoggingConfiguration(); + lc1.setId("lc2"); + lc1.setLable("two"); + lc1.setLongName("second lc"); + + em.persist(lc); + em.persist(lc1); + + em.clear(); + + em.createNativeQuery( + "insert into \"LoggingConfiguration\" (key,label,logname,nnow) values ('1','one','first lc','now')", + LoggingConfiguration.class).executeUpdate(); + em.createNativeQuery( + "insert into \"LoggingConfiguration\" (key,label,logname,nnow) values ('2','two','second log','now')", + LoggingConfiguration.class).executeUpdate(); + + Query query = em.createQuery("SELECT lc FROM LoggingConfiguration lc WHERE lc.logname = :logname", + LoggingConfiguration.class); + query.setParameter("logname", "first lc"); + List matchingConfigurations = query.getResultList(); + + int count = 0; + Assert.assertNotNull(matchingConfigurations); + for (LoggingConfiguration configuration : matchingConfigurations) + { + if (configuration.getId().equals("1")) + { + Assert.assertNotNull(configuration.getNnow()); + Assert.assertEquals("one", configuration.getLable()); + Assert.assertEquals("first lc", configuration.getLongName()); + count++; + } + else + { + Assert.assertNull(configuration.getNnow()); + Assert.assertEquals("one", configuration.getLable()); + Assert.assertEquals("lc1", configuration.getId()); + Assert.assertEquals("first lc", configuration.getLongName()); + count++; + } + } + Assert.assertEquals(2, count); + matchingConfigurations = em.createNativeQuery("SELECT * FROM \"LoggingConfiguration\"", + LoggingConfiguration.class).getResultList(); + Assert.assertNotNull(matchingConfigurations); + for (LoggingConfiguration configuration : matchingConfigurations) + { + if (configuration.getId().equals("1")) + { + Assert.assertNotNull(configuration.getNnow()); + Assert.assertEquals("one", configuration.getLable()); + Assert.assertEquals("first lc", configuration.getLongName()); + count++; + } + else if (configuration.getId().equals("2")) + { + Assert.assertNotNull(configuration.getNnow()); + Assert.assertEquals("two", configuration.getLable()); + Assert.assertEquals("second log", configuration.getLongName()); + count++; + } + else if (configuration.getId().equals("lc1")) + { + Assert.assertNull(configuration.getNnow()); + Assert.assertEquals("one", configuration.getLable()); + Assert.assertEquals("lc1", configuration.getId()); + Assert.assertEquals("first lc", configuration.getLongName()); + count++; + } + else + { + Assert.assertNull(configuration.getNnow()); + Assert.assertEquals("two", configuration.getLable()); + Assert.assertEquals("lc2", configuration.getId()); + Assert.assertEquals("second lc", configuration.getLongName()); + count++; + } + } + Assert.assertEquals(6, count); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/OTMCRUDCQLTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/OTMCRUDCQLTest.java new file mode 100644 index 000000000..838c49496 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/OTMCRUDCQLTest.java @@ -0,0 +1,40 @@ +/** + * + */ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.OTMCRUDTest; + +/** + * @author impadmin + * + */ +public class OTMCRUDCQLTest extends OTMCRUDTest +{ + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + super.setUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/PersonCassandraCQLTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/PersonCassandraCQLTest.java new file mode 100644 index 000000000..ef1a8abb8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/PersonCassandraCQLTest.java @@ -0,0 +1,31 @@ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.PersonCassandraTest; +import com.impetus.kundera.PersistenceProperties; + +public class PersonCassandraCQLTest extends PersonCassandraTest +{ + + @Before + public void setUp() throws Exception + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + AUTO_MANAGE_SCHEMA = true; + USE_CQL = true; + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/StudentCassandraCQLTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/StudentCassandraCQLTest.java new file mode 100644 index 000000000..0d2dbee9f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/StudentCassandraCQLTest.java @@ -0,0 +1,31 @@ +package com.impetus.client.cassandra.thrift.cql; + +import java.util.HashMap; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.datatypes.StudentCassandraTest; +import com.impetus.kundera.PersistenceProperties; + +public class StudentCassandraCQLTest extends StudentCassandraTest +{ + + @Before + public void setUp() throws Exception + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + AUTO_MANAGE_SCHEMA = true; + cqlEnabled = true; + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/SuperCountersTestOnCql.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/SuperCountersTestOnCql.java new file mode 100644 index 000000000..acb681f00 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/cql/SuperCountersTestOnCql.java @@ -0,0 +1,26 @@ +package com.impetus.client.cassandra.thrift.cql; + +import org.junit.After; +import org.junit.Before; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.countercolumns.SuperCountersTest; +import com.impetus.kundera.PersistenceProperties; + +public class SuperCountersTestOnCql extends SuperCountersTest +{ + + @Before + public void setUp() throws Exception + { + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/AddressMToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/AddressMToM.java new file mode 100644 index 000000000..79938dec4 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/AddressMToM.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "ADDRESSM2M", schema = "KunderaExamples@thriftClientTest") +public class AddressMToM +{ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + @Column(name = "STREET") + private String street; + + public String getAddressId() + { + return addressId; + } + + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/PersonMToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/PersonMToM.java new file mode 100644 index 000000000..bc4f72c54 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/cassandra/thrift/entities/PersonMToM.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.cassandra.thrift.entities; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "PERSONM2M", schema = "KunderaExamples@thriftClientTest") +public class PersonMToM +{ + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "PERSON_NAME") + private String personName; + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinTable(name = "PERSON_ADDRESS", joinColumns = { @JoinColumn(name = "PERSON_ID") }, inverseJoinColumns = { @JoinColumn(name = "ADDRESS_ID") }) + private Set addresses; + + public String getPersonId() + { + return personId; + } + + public String getPersonName() + { + return personName; + } + + public void setPersonName(String personName) + { + this.personName = personName; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public Set getAddresses() + { + return addresses; + } + + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/BaseTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/BaseTest.java new file mode 100644 index 000000000..32b12ca32 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/BaseTest.java @@ -0,0 +1,312 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import com.impetus.client.crud.PersonCassandra.Day; + +/** + * The Class BaseTest. + * + * @author vivek.mishra + */ +public abstract class BaseTest +{ + + /** + * Prepare data. + * + * @param rowKey + * the row key + * @param age + * the age + * @return the person + */ + protected PersonCassandra prepareData(String rowKey, int age) + { + PersonCassandra o = new PersonCassandra(); + o.setPersonId(rowKey); + o.setPersonName("vivek"); + o.setAge(age); + o.setDay(Day.THURSDAY); + o.setMonth(Month.APRIL); + return o; + } + + /** + * Find by id. + * + * @param + * the element type + * @param clazz + * the clazz + * @param rowKey + * the row key + * @param em + * the em + * @return the e + */ + protected E findById(Class clazz, Object rowKey, EntityManager em) + { + return em.find(clazz, rowKey); + } + + /** + * Assert find by name. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param fieldName + * the field name + */ + protected void assertFindByName(EntityManager em, String clazz, E e, String name, + String fieldName) + { + + String query = "Select p from " + clazz + " p where p." + fieldName + " = " + name; + // // find by name. + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + + } + + protected void assertFindByGTId(EntityManager em, String clazz, E e, String id, String fieldName) + { + String query = "Select p from " + clazz + " p where p." + fieldName + " = " + id; + // // find by name. + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert find by name and age. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAge(EntityManager em, String clazz, E e, String name, + String minVal, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find by name and age gt and lt. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeGTAndLT(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // // find by name, age clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal + " and p.age < " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(1, results.size()); + } + + /** + * Assert find by name and age between. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeBetween(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // find by between clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + + " and p.age between " + minVal + " and " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + + } + + /** + * Assert find by range. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByRange(EntityManager em, String clazz, E e, String minVal, + String maxVal, String fieldName) + + { + // find by Range. + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " Between " + minVal + " and " + + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find without where clause. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + */ + protected void assertFindWithoutWhereClause(EntityManager em, String clazz, E e) + { + // find by without where clause. + Query q = em.createQuery("Select p from " + clazz + " p"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert on merge. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param oldName + * the old name + * @param newName + * the new name + * @param fieldName + * the field name + */ + protected void assertOnMerge(EntityManager em, String clazz, E e, String oldName, + String newName, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + oldName); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + newName); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertNotSame(oldName, getPersonName(e, results.get(0))); + Assert.assertEquals(newName, getPersonName(e, results.get(0))); + } + + /** + * Gets the person name. + * + * @param + * the element type + * @param e + * the e + * @param result + * the result + * @return the person name + */ + private String getPersonName(E e, Object result) + { + + return ((PersonCassandra) result).getPersonName(); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraAuthenticationTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraAuthenticationTest.java new file mode 100644 index 000000000..d1ff25cf7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraAuthenticationTest.java @@ -0,0 +1,278 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.auth.IAuthenticator; +import org.apache.cassandra.thrift.AuthenticationException; +import org.apache.cassandra.thrift.AuthenticationRequest; +import org.apache.cassandra.thrift.AuthorizationException; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * The Class CassandraAuthenticationTest to test scenarios for cassandra + * authentication test. + * + * @author vivek.mishra + */ +public class CassandraAuthenticationTest extends BaseTest +{ + + private String userName; + + private String password; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + // userName = "kunderauser"; + // password = "kunderapassword"; + // System.setProperty("passwd.properties", + // "../resources/passwd.properties"); + // System.setProperty("access.properties", + // "../resources/access.properties"); + // + // CassandraCli.cassandraSetUp(); + } + + @Test + public void testDummy() + { + // do nothing. + // please do not modify this test at all! + } + + /** + * Authenticate with valid credentials. + */ + // @Test + public void authenticateWithValidCredentials() + { + try + { + EntityManagerFactory emf = Persistence.createEntityManagerFactory("authenticationTest"); + Assert.assertNotNull(emf); + loadData(); + EntityManager em = emf.createEntityManager(); + Assert.assertNotNull(em); + PersonAuth o = new PersonAuth(); + o.setPersonId("1"); + o.setPersonName("vivek"); + o.setAge(10); + em.persist(o); + + PersonAuth p = em.find(PersonAuth.class, "1"); + Assert.assertNotNull(p); + + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + + } + + /** + * Authenticate with invalid credentials. + * + * @throws SchemaDisagreementException + * @throws TimedOutException + * @throws UnavailableException + * @throws InvalidRequestException + * @throws TException + * @throws IOException + */ + // @Test + public void authenticateWithInValidCredentials() throws IOException, TException, InvalidRequestException, + UnavailableException, TimedOutException, SchemaDisagreementException + { + EntityManagerFactory emf = null; + EntityManager em = null; + try + { + userName = "kunderauser"; + password = "invalid"; + loadData(); + emf = Persistence.createEntityManagerFactory("invalidauthenticationTest"); + em = emf.createEntityManager(); + Assert.fail("Shouldn't be called"); + } + catch (AuthenticationException e) + { + Assert.assertNull(emf); + Assert.assertNull(em); + userName = "kunderauser"; + password = "kunderapassword"; + } + catch (AuthorizationException e) + { + Assert.assertNull(emf); + Assert.assertNull(em); + userName = "kunderauser"; + password = "kunderapassword"; + } + + } + + /** + * No authentication test. + * + */ + // @Test + public void noAuthenticationTest() + { + try + { + EntityManagerFactory emf = Persistence.createEntityManagerFactory("cass_pu"); + Assert.assertNotNull(emf); + EntityManager em = emf.createEntityManager(); + Assert.assertNotNull(em); + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + * @throws AuthorizationException + * @throws AuthenticationException + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException, AuthenticationException, AuthorizationException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSON"; + user_Def.keyspace = "KunderaAuthentication"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + Map credentials = new HashMap(); + credentials.put(IAuthenticator.USERNAME_KEY, userName); + credentials.put(IAuthenticator.PASSWORD_KEY, password); + CassandraCli.client.login(new AuthenticationRequest(credentials)); + + CassandraCli.createKeySpace("KunderaAuthentication"); + + ksDef = CassandraCli.client.describe_keyspace("KunderaAuthentication"); + CassandraCli.client.set_keyspace("KunderaAuthentication"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON")) + { + + CassandraCli.client.system_drop_column_family("PERSON"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaAuthentication", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + ksDef.setReplication_factor(1); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaAuthentication"); + + } + + /** + * Tear down. + * + * @throws TException + * @throws AuthorizationException + * @throws AuthenticationException + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws AuthenticationException, AuthorizationException, TException + { + // Map credentials = new HashMap(); + // credentials.put(IAuthenticator.USERNAME_KEY, userName); + // credentials.put(IAuthenticator.PASSWORD_KEY, password); + // CassandraCli.client.login(new AuthenticationRequest(credentials)); + // + // CassandraCli.dropKeySpace("KunderaAuthentication"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraIdQueryTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraIdQueryTest.java new file mode 100644 index 000000000..817b6ef8a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/CassandraIdQueryTest.java @@ -0,0 +1,619 @@ +/** + * + */ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * @author Kuldeep Mishra + * + */ +public class CassandraIdQueryTest extends BaseTest +{ + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + private Map col; + + private CassandraCli cli; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + emf = Persistence.createEntityManagerFactory("secIdxCassandraTest", propertyMap); + loadData(); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (Object val : col.values()) + { + em.remove(val); + } + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + @Test + public void test() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + init(); + em.clear(); + findById(); + findByWithOutWhereClause(); + findByIdEQ(); + findByIdLT(); + findByIdLTE(); + findByIdGT(); + findByIdGTE(); + findByIdGTEAndLT(); + findByIdGTAndLTE(); + findByIdAndAgeGTAndLT(); + findByIdGTAndAgeGTAndLT(); + findByIdAndAge(); + findByIdAndAgeGT(); + findByIdGTEAndAge(); + findByIdLTEAndAge(); + } + + /** + * + */ + private void findByWithOutWhereClause() + { + String qry = "Select p.personName from PersonCassandra p"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + + } + + /** + * + */ + private void findByIdEQ() + { + String qry = "Select p.personName from PersonCassandra p where p.personId = 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonCassandra person : persons) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("2", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + } + + /** + * + */ + private void findByIdLT() + { + String qry = "Select p.personName from PersonCassandra p where p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdLTE() + { + String qry = "Select p.personName, p.age from PersonCassandra p where p.personId <= 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertEquals(new Integer("20"), person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertEquals(new Integer("15"), person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertEquals(new Integer("10"), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGT() + { + String qry = "Select p.personName from PersonCassandra p where p.personId > 1"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTE() + { + String qry = "Select p.personName from PersonCassandra p where p.personId >= 1 "; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTEAndLT() + { + String qry = "Select p.personName from PersonCassandra p where p.personId >= 1 and p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTAndLTE() + { + String qry = "Select p.personName from PersonCassandra p where p.personId > 1 and p.personId <= 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertEquals("1", person.getPersonId()); + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findByIdGTAndAgeGTAndLT() + { + + String qry = "Select p.personName from PersonCassandra p where p.personId > 1 and p.personName = vivek and p.age >=10 and p.age <= 20"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findById() + { + PersonCassandra personHBase = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(10), personHBase.getAge()); + + personHBase = findById(PersonCassandra.class, "2", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(20), personHBase.getAge()); + + personHBase = findById(PersonCassandra.class, "3", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(15), personHBase.getAge()); + } + + /** + * + */ + private void findByIdGTEAndAge() + { + String qry = "Select p.personName, p.age from PersonCassandra p where p.personId >= 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonCassandra person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + } + + /** + * + */ + private void findByIdAndAge() + { + String qry = "Select p.personName, p.age from PersonCassandra p where p.personId = 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonCassandra person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + Assert.assertEquals(10, person.getAge().intValue()); + Assert.assertNull(person.getA()); + } + } + + /** + * + */ + private void findByIdAndAgeGT() + { + String qry = "Select p.personName, p.age from PersonCassandra p where p.personId = 1 and p.age > 5"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonCassandra person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + Assert.assertEquals(10, person.getAge().intValue()); + Assert.assertNull(person.getA()); + } + } + + /** + * + */ + private void findByIdAndAgeGTAndLT() + { + String qry = "Select p.personName from PersonCassandra p where p.personId = 1 and p.personName = vivek and p.age >=10 and p.age <= 20"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + int count = 0; + for (PersonCassandra person : persons) + { + if (person.getPersonId().equals("1")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(1, count); + } + + /** + * + */ + private void findByIdLTEAndAge() + { + String qry = "Select p.personName, p.age from PersonCassandra p where p.personId <= 3 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonCassandra person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + + } + + private void init() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSONCASSANDRA"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "IntegerType"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("ENUM".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSONCASSANDRA")) + { + + CassandraCli.client.system_drop_column_family("PERSONCASSANDRA"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Employee.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Employee.java new file mode 100644 index 000000000..63f6a339b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Employee.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "PERSON", schema = "KunderaExamples@secIdxCassandraTest") +public class Employee +{ + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "PERSON_NAME") + private String personName; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "manager") + private Set Employees; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "MANAGER_ID") + private Employee manager; + + public Employee() + { + } + + /** + * @return the personId + */ + public String getPersonId() + { + return personId; + } + + /** + * @param personId + * the personId to set + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the personName + */ + public String getPersonName() + { + return personName; + } + + /** + * @param personName + * the personName to set + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * @return the employees + */ + public Set getEmployees() + { + return Employees; + } + + /** + * @param employees + * the employees to set + */ + public void setEmployees(Set employees) + { + Employees = employees; + } + + /** + * @return the manager + */ + public Employee getManager() + { + return manager; + } + + /** + * @param manager + * the manager to set + */ + public void setManager(Employee manager) + { + this.manager = manager; + } + + // Constructors, Getters, setters here +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/EntityTransactionTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/EntityTransactionTest.java new file mode 100644 index 000000000..5685082b3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/EntityTransactionTest.java @@ -0,0 +1,405 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * The Class EntityTransactionTest. + * + * @author vivek.mishra + */ +public class EntityTransactionTest extends BaseTest +{ + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + + // cassandraSetUp(); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + loadData(); + + emf = Persistence.createEntityManagerFactory("secIdxCassandraTest"); + em = emf.createEntityManager(); + } + + /** + * On rollback. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + @Test + public void onRollback() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + + em.getTransaction().begin(); + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + // roll back. + em.getTransaction().rollback(); + + em.getTransaction().begin(); + + PersonCassandra p = findById(PersonCassandra.class, "1", em); + Assert.assertNull(p); + + // on commit. + em.getTransaction().commit(); + + // Still no record should be flushed as already rollback! + p = findById(PersonCassandra.class, "1", em); + Assert.assertNull(p); + } + + /** + * On commit. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + @Test + public void onCommit() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + + em.getTransaction().begin(); + + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + // on commit. + em.getTransaction().commit(); + + PersonCassandra p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + + em.getTransaction().begin(); + + ((PersonCassandra) p2).setPersonName("rollback"); + em.merge(p2); + + // roll back, should roll back person name for p2! + em.getTransaction().rollback(); + + p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + + p = findById(PersonCassandra.class, "2", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + Assert.assertNotSame("rollback", p.getPersonName()); + + } + + /** + * Rollback on error. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + @Test + public void rollbackOnError() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + PersonCassandra p = null; + try + { + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + em.persist(p1); + em.persist(p2); + + p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + + Object p3 = prepareData("3", 15); + em.persist(p3); + + // Assert on rollback on error. + ((PersonCassandra) p2).setPersonName("rollback"); + em.merge(p2); + em.merge(null); + + // As this is a runtime exception so rollback should happen and + // delete out commited data. + } + catch (Exception ex) + { + + p = findById(PersonCassandra.class, "1", em); + Assert.assertNull(p); + + p = findById(PersonCassandra.class, "2", em); + Assert.assertNull(p); + + p = findById(PersonCassandra.class, "3", em); + Assert.assertNull(p); + } + em.clear(); + // persist with 1 em + EntityManager em1 = emf.createEntityManager(); + // em1.setFlushMode(FlushModeType.COMMIT); + em1.getTransaction().begin(); + Object p3 = prepareData("4", 15); + em1.persist(p3); + em1.getTransaction().commit(); + + try + { + // remove with another em with auto flush. + EntityManager em2 = emf.createEntityManager(); + PersonCassandra person = em2.find(PersonCassandra.class, "4"); + em2.remove(person); + em2.merge(null); + } + catch (Exception ex) + { + // Deleted records cannot be rolled back in cassandra! + // em1.clear(); + + p = findById(PersonCassandra.class, "4", em1); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + + } + } + + /** + * Roll back with multi transactions. + */ + @Test + public void rollBackWithMultiTransactions() + { + EntityManager em1 = emf.createEntityManager(); + // em1.setFlushMode(FlushModeType.COMMIT); + + // Begin transaction. + em1.getTransaction().begin(); + Object p1 = prepareData("11", 10); + em1.persist(p1); + + // commit p1. + em1.getTransaction().commit(); + + // another em instance + EntityManager em2 = emf.createEntityManager(); + // em2.setFlushMode(FlushModeType.COMMIT); + + // begin transaction. + em2.getTransaction().begin(); + PersonCassandra found = em2.find(PersonCassandra.class, "11"); + found.setPersonName("merged"); + em2.merge(found); + + // commit p1 after modification. + em2.getTransaction().commit(); + + // open another entity manager. + EntityManager em3 = emf.createEntityManager(); + found = em3.find(PersonCassandra.class, "11"); + found.setPersonName("lastemerge"); + try + { + em3.merge(found); + em3.merge(null); + } + catch (Exception ex) + { + PersonCassandra finalFound = em2.find(PersonCassandra.class, "11"); + Assert.assertNotNull(finalFound); + Assert.assertEquals("merged", finalFound.getPersonName()); + } + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + {/* + * Delete is working, but as row keys are not deleted from cassandra, so + * resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); em.remove(em.find(Person.class, + * "2")); em.remove(em.find(Person.class, "3")); em.close(); emf.close(); + * em = null; emf = null; + */ + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSONCASSANDRA"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("ENUM".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON")) + { + + CassandraCli.client.system_drop_column_family("PERSON"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Group.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Group.java new file mode 100644 index 000000000..3658607c1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Group.java @@ -0,0 +1,82 @@ +package com.impetus.client.crud; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "groups", schema = "KunderaExamples@secIdxCassandraTest") +@IndexCollection(columns = { @Index(name = "parentId") }) +public class Group +{ + + @Id + @Column(name = "resourceId") + private String resourceId; + + @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + @JoinColumn(name = "parentId") + private Group parent; + + @OneToMany(fetch = FetchType.EAGER, mappedBy = "parent") + private List children; + + @Column(name = "resourceName") + private String resourceName; + + public Group() + { + } + + public Group getParent() + { + return parent; + } + + public void setParent(Group parent) + { + this.parent = parent; + } + + public List getChildren() + { + return children; + } + + public void setChildren(List children) + { + this.children = children; + } + + public String getResourceId() + { + return resourceId; + } + + public void setResourceId(String resourceId) + { + this.resourceId = resourceId; + } + + public String getResourceName() + { + return resourceName; + } + + public void setResourceName(String resourceName) + { + this.resourceName = resourceName; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MTOBiSelfAssociationTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MTOBiSelfAssociationTest.java new file mode 100644 index 000000000..73918ff6b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MTOBiSelfAssociationTest.java @@ -0,0 +1,128 @@ +package com.impetus.client.crud; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +public class MTOBiSelfAssociationTest +{ + + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + protected Map propertyMap = null; + + protected boolean AUTO_MANAGE_SCHEMA = true; + + protected boolean USE_CQL = false; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + + if (AUTO_MANAGE_SCHEMA) + { + // loadData(); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + } + + @Test + public void test() + { + Group all = new Group(); + all.setResourceId("All"); // A + all.setResourceName("resName"); + + Group ungrouped = new Group(); + ungrouped.setResourceId("ungrouped"); + ungrouped.setParent(all); // B + + Group grouped = new Group(); + grouped.setResourceId("grouped"); + grouped.setParent(all); // C + + List children = new ArrayList(); + children.add(ungrouped); + children.add(grouped); + all.setChildren(children); + + em.persist(ungrouped); + em.persist(grouped); + em.persist(all); + + em.clear(); + Group parent = em.find(Group.class, "All"); + + Assert.assertNotNull(parent); + Assert.assertNotNull(parent.getChildren()); + Assert.assertNull(parent.getParent()); + Assert.assertEquals(2, parent.getChildren().size()); + Assert.assertSame(parent, parent.getChildren().iterator().next().getParent()); + Assert.assertSame(parent, parent.getChildren().iterator().next().getParent()); + + em.clear(); + Group child1 = em.find(Group.class, "ungrouped"); + Assert.assertNotNull(child1); + Assert.assertEquals(child1.getParent().getResourceId(), "All"); + Assert.assertNull(child1.getParent().getParent()); + Assert.assertEquals(child1.getResourceId(), "ungrouped"); + Assert.assertEquals(2, child1.getParent().getChildren().size()); + Assert.assertSame(child1.getParent().getChildren().iterator().next().getParent(), child1.getParent() + .getChildren().iterator().next().getParent()); + + em.clear(); + Group child2 = em.find(Group.class, "grouped"); + Assert.assertNotNull(child2); + Assert.assertEquals(child2.getParent().getResourceId(), "All"); + Assert.assertNull(child2.getParent().getParent()); + Assert.assertEquals(child2.getResourceId(), "grouped"); + Assert.assertEquals(2, child2.getParent().getChildren().size()); + Assert.assertSame(child2.getParent().getChildren().iterator().next().getParent(), child2.getParent() + .getChildren().iterator().next().getParent()); + + } + + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Month.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Month.java new file mode 100644 index 000000000..484cdd1b3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Month.java @@ -0,0 +1,6 @@ +package com.impetus.client.crud; + +enum Month +{ + JAN, FEB, MARCH, APRIL, MAY, JUNE; +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MyTestEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MyTestEntity.java new file mode 100644 index 000000000..ac896e2a9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/MyTestEntity.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.io.Serializable; +import java.sql.Timestamp; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "test1", schema = "KunderaCassandraXmlTest@CassandraXmlPropertyTest") +@IndexCollection(columns = { @Index(name = "url") }) +public class MyTestEntity implements Serializable +{ + + private static final long serialVersionUID = 1L; + + @Id + @Column(name = "id") + private UUID key; + + @Column(name = "userid") + private UUID userid; + + @Column(name = "url") + private String url; + + @Column(name = "datetime") + private Timestamp datetime; + + @Column(name = "linkcounts") + private int linkcounts; + + public MyTestEntity() + { + } + + public UUID getKey() + { + return key; + } + + public void setKey(UUID key) + { + this.key = key; + } + + public UUID getUserid() + { + return userid; + } + + public void setUserid(UUID userid) + { + this.userid = userid; + } + + public String getUrl() + { + return url; + } + + public void setUrl(String url) + { + this.url = url; + } + + public Timestamp getDatetime() + { + return datetime; + } + + public void setDatetime(Timestamp datetime) + { + this.datetime = datetime; + } + + public int getLinkcounts() + { + return linkcounts; + } + + public void setLinkcounts(int linkcounts) + { + this.linkcounts = linkcounts; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/OTMCRUDTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/OTMCRUDTest.java new file mode 100644 index 000000000..44d4fa822 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/OTMCRUDTest.java @@ -0,0 +1,111 @@ +package com.impetus.client.crud; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +public class OTMCRUDTest +{ + + private static final String SEC_IDX_CASSANDRA_TEST = "myapp_pu"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + protected Map propertyMap = null; + + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + CassandraCli.createKeySpace("myapp"); + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + } + + @After + public void tearDown() throws Exception + { + String query = "Delete t from Token t"; + Query q = em.createQuery(query); + q.executeUpdate(); + + if (emf != null) + { + emf.close(); + emf = null; + } + if (em != null) + { + em.close(); + em = null; + } + + CassandraCli.dropKeySpace("myapp"); + } + + @Test + public void test() + { + Token token1 = new Token(); + token1.setId("tokenId1"); + TokenClient client = new TokenClient(); + client.setClientName("tokenClient1"); + client.setId("tokenClientId"); + token1.setClient(client); + + Token token2 = new Token(); + token2.setId("tokenId2"); + token2.setClient(client); + em.persist(token1); + em.persist(token2); + + em.clear(); + Token result = em.find(Token.class, "tokenId1"); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getClient()); + + em.clear(); + String query = "Select t from Token t"; + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertNotNull(results.get(0).getClient()); + Assert.assertNotNull(results.get(1).getClient()); + + em.clear(); + query = "Select t from TokenClient t"; + q = em.createQuery(query); + List resultClient = q.getResultList(); + Assert.assertNotNull(resultClient); + Assert.assertEquals(1, resultClient.size()); + Assert.assertEquals(2, resultClient.get(0).getTokens().size()); + + em.clear(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAssociationTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAssociationTest.java new file mode 100644 index 000000000..a61089f1d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAssociationTest.java @@ -0,0 +1,234 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Test case to perform simple SelfAssociation. + * + * @author vivek.mishra + * + * Run this script to create column family in cassandra with indexes. + * create column family PERSON with comparator=UTF8Type and + * column_metadata=[{column_name: PERSON_NAME, + * validation_class:UTF8Type, index_type: KEYS}, {column_name: + * AGE,validation_class:IntegerType, index_type: KEYS}, {column_name: + * MANAGER_ID,validation_class:UTF8Type, index_type: KEYS}]; + * + */ +public class PersonAssociationTest extends BaseTest +{ + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + private CassandraCli cassandraCli; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + cassandraCli = new CassandraCli(); + cassandraCli.cassandraSetUp(); + loadData(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + emf = Persistence.createEntityManagerFactory("secIdxCassandraTest"); + em = emf.createEntityManager(); + } + + @Test + public void testDemo() + { + + } + + /** + * On crud. + */ + // @Test + public void onInsert() + { + + Employee emp1 = new Employee(); + emp1.setPersonId("1_e"); + emp1.setPersonName("emp"); + + Employee emp2 = new Employee(); + emp2.setPersonId("2_e"); + emp2.setPersonName("emp2"); + + Employee manager = new Employee(); + manager.setPersonId("2_m"); + manager.setPersonName("mgr"); + emp1.setManager(manager); + + // set manager for employee2 + emp2.setManager(manager); + // set manager for employee1 + emp1.setManager(manager); + + Set ems = new java.util.HashSet(); + ems.add(emp2); + ems.add(emp1); + + // set employees for manager. + manager.setEmployees(ems); + + em.persist(emp1); + em.persist(emp2); + // em.persist(manager); + + em.clear(); + Employee emp = em.find(Employee.class, "1_e"); + + Assert.assertNotNull(emp); + Assert.assertEquals("2_m", emp.getManager().getPersonId()); + Assert.assertNull(emp.getEmployees()); + Assert.assertNotNull(emp.getManager().getEmployees()); + Assert.assertFalse(emp.getManager().getEmployees().isEmpty()); + Assert.assertEquals(2, emp.getManager().getEmployees().size()); + Iterator iter = emp.getManager().getEmployees().iterator(); + String firstEmployee = iter.next().getPersonId(); + String secEmployee = iter.next().getPersonId(); + Assert.assertNotSame(firstEmployee, secEmployee); + // Assert.assertEquals("2_e", + // emp.getEmployees().iterator().next().getPersonId()); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSON"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + ColumnDef personName = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + personName.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(personName); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "IntegerType"); + age.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(age); + + ColumnDef reference_key = new ColumnDef(ByteBuffer.wrap("MANAGER_ID".getBytes()), "UTF8Type"); + reference_key.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(reference_key); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON")) + { + + CassandraCli.client.system_drop_column_family("PERSON"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + cassandraCli.dropKeySpace("KunderaExamples"); + /* + * Delete is working, but as row keys are not deleted from cassandra, so + * resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); + * em.remove(em.find(Person.class, "2")); + * em.remove(em.find(Person.class, "3")); em.close(); emf.close(); em = + * null; emf = null; + */ + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAuth.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAuth.java new file mode 100644 index 000000000..85bb85fd6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonAuth.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON", schema = "KunderaAuthentication@authenticationTest") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class PersonAuth +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandra.java new file mode 100644 index 000000000..c1b60c5da --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandra.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "PERSONCASSANDRA", schema = "KunderaExamples@secIdxCassandraTest") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class PersonCassandra +{ + public static final String UID = "uid"; + + public static final String EID = "eid"; + + public static final String FIRST_NAME = "firstName"; + + public static final String LAST_NAME = "lastName"; + + public static final String CITY = "city"; + + public static final String CREATED = "created"; + + public static final String LAST_MODIFIED = "lastModified"; + + /** The person id. */ + @Id + // @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + @Column(name = "ENUM") + @Enumerated(EnumType.STRING) + private Day day; + + @Column(name = "MONTH_ENUM") + @Enumerated(EnumType.STRING) + private Month month; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the day + */ + public Day getDay() + { + return day; + } + + /** + * @param day + * the day to set + */ + public void setDay(Day day) + { + this.day = day; + } + + public Month getMonth() + { + return month; + } + + public void setMonth(Month month) + { + this.month = month; + } + + enum Day + { + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraLuceneTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraLuceneTest.java new file mode 100644 index 000000000..6a149b891 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraLuceneTest.java @@ -0,0 +1,618 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.TypedQuery; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.utils.LuceneCleanupUtilities; + +/** + * Test case to perform simple CRUD operation.(insert, delete, merge, and + * select) + * + * @author kuldeep.mishra + * + * Run this script to create column family in cassandra with indexes. + * create column family PERSON with comparator=UTF8Type and + * column_metadata=[{column_name: PERSON_NAME, validation_class: + * UTF8Type, index_type: KEYS}, {column_name: AGE, validation_class: + * IntegerType, index_type: KEYS}]; + * + */ +public class PersonCassandraLuceneTest extends BaseTest +{ + private static final String LUCENE_IDX_CASSANDRA_TEST = "luceneCassandraTest"; + + private static final boolean USE_CQL = false; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** The col. */ + private Map col; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + loadData(); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + emf = Persistence.createEntityManagerFactory(LUCENE_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * On insert cassandra. + * + * @throws Exception + * the exception + */ + @Test + public void onInsertCassandra() throws Exception + { + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + + em.clear(); + PersonLuceneCassandra p = findById(PersonLuceneCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + + em.clear(); + String qry = "Select p.personId,p.personName from PersonLuceneCassandra p where p.personId >= 1"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + + assertFindByName(em, "PersonLuceneCassandra", PersonLuceneCassandra.class, "vivek", "personName"); + assertFindByNameAndAge(em, "PersonLuceneCassandra", PersonLuceneCassandra.class, "vivek", "10", "personName"); + assertFindByNameAndAgeGTAndLT(em, "PersonLuceneCassandra", PersonLuceneCassandra.class, "vivek", "10", "20", + "personName"); + assertFindByNameAndAgeBetween(em, "PersonLuceneCassandra", PersonLuceneCassandra.class, "vivek", "10", "15", + "personName"); + assertFindByRange(em, "PersonLuceneCassandra", PersonLuceneCassandra.class, "1", "2", "personId"); + assertFindWithoutWhereClause(em, "PersonLuceneCassandra", PersonLuceneCassandra.class); + + // OR clause test case. + String orClauseQuery = "Select p from PersonLuceneCassandra p where p.personName = 'vivek1' OR p.age = 10"; + + q = em.createQuery(orClauseQuery); + + List results = q.getResultList(); + + Assert.assertEquals(1, results.size()); + // perform merge after query. + for (PersonLuceneCassandra person : persons) + { + person.setPersonName("after merge"); + em.merge(person); + } + + em.clear(); + + // select rowid test + selectIdQuery(); + + em.clear(); + + p = findById(PersonLuceneCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("after merge", p.getPersonName()); + + // Delete without WHERE clause. + + String deleteQuery = "DELETE from PersonLuceneCassandra"; + q = em.createQuery(deleteQuery); + Assert.assertEquals(3, q.executeUpdate()); + + } + + /** + * On merge cassandra. + * + * @throws Exception + * the exception + */ + @Test + public void onMergeCassandra() throws Exception + { + // CassandraCli.cassandraSetUp(); + // loadData(); + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + em.clear(); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + PersonLuceneCassandra p = findById(PersonLuceneCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + // modify record. + p.setPersonName("newvivek"); + em.merge(p); + + assertOnMerge(em, "PersonLuceneCassandra", "vivek", "newvivek", "personName"); + } + + @Test + public void onDeleteThenInsertCassandra() throws Exception + { + // CassandraCli.cassandraSetUp(); + // CassandraCli.initClient(); + // loadData(); + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + PersonLuceneCassandra p = findById(PersonLuceneCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + em.remove(p); + em.clear(); + + TypedQuery query = em.createQuery("Select p from PersonLuceneCassandra p", + PersonLuceneCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + p1 = prepare("1", 10); + em.persist(p1); + + query = em.createQuery("Select p from PersonLuceneCassandra p", PersonLuceneCassandra.class); + + results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + } + + @Test + public void onRefreshCassandra() throws Exception + { + // cassandraSetUp(); + // CassandraCli.cassandraSetUp(); + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + CassandraCli.client.set_keyspace("KunderaExamples"); + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + + // Check for contains + Object pp1 = prepare("1", 10); + Object pp2 = prepare("2", 20); + Object pp3 = prepare("3", 15); + Assert.assertTrue(em.contains(pp1)); + Assert.assertTrue(em.contains(pp2)); + Assert.assertTrue(em.contains(pp3)); + + // Check for detach + em.detach(pp1); + em.detach(pp2); + Assert.assertFalse(em.contains(pp1)); + Assert.assertFalse(em.contains(pp2)); + Assert.assertTrue(em.contains(pp3)); + + // Modify value in database directly, refresh and then check PC + em.clear(); + em = emf.createEntityManager(); + Object o1 = em.find(PersonLuceneCassandra.class, "1"); + + if (!USE_CQL) + { + // Create Insertion List + List insertionList = new ArrayList(); + List columns = new ArrayList(); + Column column = new Column(); + column.setName(PropertyAccessorFactory.STRING.toBytes("PERSON_NAME")); + column.setValue(PropertyAccessorFactory.STRING.toBytes("Amry")); + column.setTimestamp(System.currentTimeMillis()); + columns.add(column); + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setColumn(column)); + insertionList.add(mut); + // Create Mutation Map + Map> columnFamilyValues = new HashMap>(); + columnFamilyValues.put("PERSON", insertionList); + Map>> mulationMap = new HashMap>>(); + mulationMap.put(ByteBuffer.wrap("1".getBytes()), columnFamilyValues); + CassandraCli.client.batch_mutate(mulationMap, ConsistencyLevel.ONE); + } + else + { + CQLTranslator translator = new CQLTranslator(); + String query = "insert into \"PERSONCASSANDRA\" (key,\"PERSON_NAME\",\"AGE\") values (1,'Amry',10 )"; + CassandraCli.client.execute_cql3_query(ByteBuffer.wrap(query.getBytes()), Compression.NONE, + ConsistencyLevel.ONE); + } + + em.refresh(o1); + Object oo1 = em.find(PersonLuceneCassandra.class, "1"); + Assert.assertTrue(em.contains(o1)); + Assert.assertEquals("Amry", ((PersonLuceneCassandra) oo1).getPersonName()); + } + + /** + * On typed create query + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onTypedQuery() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + TypedQuery query = em.createQuery("Select p from PersonLuceneCassandra p", + PersonLuceneCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + } + + /** + * On typed create query + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onGenericTypedQuery() throws TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + TypedQuery query = em.createQuery("Select p from PersonLuceneCassandra p", Object.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(PersonLuceneCassandra.class, results.get(0).getClass()); + } + + /** + * on invalid typed query. + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onInvalidTypedQuery() throws TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + TypedQuery query = null; + try + { + query = em.createQuery("Select p from PersonLuceneCassandra p", PersonAuth.class); + Assert.fail("Should have gone to catch block, as it is an invalid scenario!"); + } + catch (IllegalArgumentException iaex) + { + Assert.assertNull(query); + } + } + + @Test + public void onGhostRows() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + Object p1 = prepare("1", 10); + Object p2 = prepare("2", 20); + Object p3 = prepare("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + em.clear(); + PersonLuceneCassandra person = em.find(PersonLuceneCassandra.class, "1"); + em.remove(person); + em.clear(); // just to make sure that not to be picked up from cache. + TypedQuery query = em.createQuery("Select p from PersonLuceneCassandra p", + PersonLuceneCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + } + + private void selectIdQuery() + {/* + * String query = "select p.personId from PersonLuceneCassandra p"; Query q + * = em.createQuery(query); List results = + * q.getResultList(); Assert.assertNotNull(results); Assert.assertEquals(3, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * + * query = + * "Select p.personId from PersonLuceneCassandra p where p.personName = vivek" + * ; // // find by name. q = em.createQuery(query); results = + * q.getResultList(); Assert.assertNotNull(results); + * Assert.assertFalse(results.isEmpty()); Assert.assertEquals(3, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * Assert.assertNull(results.get(0).getAge()); + * + * q = em.createQuery( + * "Select p.personId from PersonLuceneCassandra p where p.personName = vivek and p.age > " + * + 10); results = q.getResultList(); Assert.assertNotNull(results); + * Assert.assertFalse(results.isEmpty()); Assert.assertEquals(2, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * Assert.assertNull(results.get(0).getAge()); + */ + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + {/* + * Delete is working, but as row keys are not deleted from cassandra, so + * resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); em.remove(em.find(Person.class, + * "2")); em.remove(em.find(Person.class, "3")); em.close(); emf.close(); + * em = null; emf = null; + */ + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + LuceneCleanupUtilities.cleanLuceneDirectory(LUCENE_IDX_CASSANDRA_TEST); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSON"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "IntegerType"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("ENUM".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON")) + { + + CassandraCli.client.system_drop_column_family("PERSON"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } + + /** + * Prepare data. + * + * @param rowKey + * the row key + * @param age + * the age + * @return the person + */ + private PersonLuceneCassandra prepare(String rowKey, int age) + { + PersonLuceneCassandra o = new PersonLuceneCassandra(); + o.setPersonId(rowKey); + o.setPersonName("vivek"); + o.setAge(age + ""); + o.setDay(com.impetus.client.crud.PersonLuceneCassandra.Day.MONDAY); + return o; + } + + private void assertOnMerge(EntityManager em, String clazz, String oldName, String newName, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + oldName); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + newName); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertNotSame(oldName, getPersonName(results.get(0))); + Assert.assertEquals(newName, getPersonName(results.get(0))); + } + + /** + * Gets the person name. + * + * @param + * the element type + * @param e + * the e + * @param result + * the result + * @return the person name + */ + private String getPersonName(Object result) + { + + return ((PersonLuceneCassandra) result).getPersonName(); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTTLTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTTLTest.java new file mode 100644 index 000000000..a17826e1f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTTLTest.java @@ -0,0 +1,514 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.ColumnParent; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.SlicePredicate; +import org.apache.cassandra.thrift.SliceRange; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.scale7.cassandra.pelops.Bytes; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Test case for verifying Time to Live feature of Cassandra on single entity + * + * @author amresh.singh + */ +public class PersonCassandraTTLTest extends BaseTest +{ + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** The col. */ + private Map col; + + protected Map propertyMap = null; + + protected boolean AUTO_MANAGE_SCHEMA = true; + + protected boolean USE_CQL = false; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + } + + @After + public void tearDown() throws Exception + { + if (em != null) + em.close(); + if (emf != null) + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + /** + * Tests whether TTL provided while inserting records are correctly getting + * applied for CQL 2.0 Common TTL value for entire row is used + * + * @throws Exception + */ + + @Test + public void testTTLForEntireRowOnCQL2_0() throws Exception + { + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + + Map ttlValues = new HashMap(); + ttlValues.put("PERSONCASSANDRA", new Integer(5)); + em.setProperty("ttl.per.request", true); + em.setProperty("ttl.values", ttlValues); + + Object p1 = prepareData("1", 10); + em.persist(p1); + em.clear(); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + + SlicePredicate predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + ByteBuffer key = ByteBuffer.wrap("1".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + List columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent( + "PERSONCASSANDRA"), predicate, ConsistencyLevel.ONE); + + boolean personNameFound = false; + boolean ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(5, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(5, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(5000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.fail("PERSON_NAME column not deleted even though a TTL of 5 seconds was specified while writing to cassandra."); + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 5 seconds was specified while writing to cassandra."); + } + } + + String deleteQuery = "DELETE from PersonCassandra"; + Query q = em.createQuery(deleteQuery); + Assert.assertEquals(0, q.executeUpdate()); + } + + /** + * Tests whether TTL provided while inserting records are correctly getting + * applied for CQL 2.0 Different TTL Values for Different columns are used + * + * @throws Exception + */ + + @Test + public void testDifferentTTLOnCQL2_0() throws Exception + { + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + + Map ttlColumns = new HashMap(); + ttlColumns.put("PERSON_NAME", 5000000); + ttlColumns.put("AGE", 5); + Map> ttlValues = new HashMap>(); + ttlValues.put("PERSONCASSANDRA", ttlColumns); + em.setProperty("ttl.per.request", true); + em.setProperty("ttl.values", ttlValues); + + Object p1 = prepareData("1", 10); + em.persist(p1); + em.clear(); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + + SlicePredicate predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + ByteBuffer key = ByteBuffer.wrap("1".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + List columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent( + "PERSONCASSANDRA"), predicate, ConsistencyLevel.ONE); + + boolean personNameFound = false; + boolean ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(5000000, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(5, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(5000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(5000000, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 5 seconds was specified while writing to cassandra."); + } + } + + String deleteQuery = "DELETE from PersonCassandra"; + Query q = em.createQuery(deleteQuery); + Assert.assertEquals(1, q.executeUpdate()); + } + + /** + * Tests whether TTL provided while inserting records are correctly getting + * applied using CQL 3 Common TTL value for entire row is used + * + * @throws Exception + */ + @Test + public void testTTLonCQL3_0() throws Exception + { + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + + Map ttlValues = new HashMap(); + ttlValues.put("PERSONCASSANDRA", new Integer(5)); + em.setProperty("ttl.per.request", true); + em.setProperty("ttl.values", ttlValues); + + Object p1 = prepareData("1", 10); + em.persist(p1); + em.clear(); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + + SlicePredicate predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + ByteBuffer key = ByteBuffer.wrap("1".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + List columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent( + "PERSONCASSANDRA"), predicate, ConsistencyLevel.ONE); + + boolean personNameFound = false; + boolean ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(5, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(5, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(5000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.fail("PERSON_NAME column not deleted even though a TTL of 5 seconds was specified while writing to cassandra."); + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 5 seconds was specified while writing to cassandra."); + } + } + + // checking for update query. + + Object p2 = prepareData("2", 10); + em.persist(p2); + em.clear(); + + ttlValues = new HashMap(); + ttlValues.put("PERSONCASSANDRA", new Integer(10)); + em.setProperty("ttl.per.request", true); + em.setProperty("ttl.values", ttlValues); + + Query q = em.createQuery("update PersonCassandra p set p.personName=''KK MISHRA'' where p.personId=2"); + q.executeUpdate(); + + predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + key = ByteBuffer.wrap("2".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + + personNameFound = false; + ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(10, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(10, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(10000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.fail("PERSON_NAME column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + } + + // TTL per session. + + ttlValues = new HashMap(); + ttlValues.put("PERSONCASSANDRA", new Integer(10)); + em.setProperty("ttl.per.session", true); + em.setProperty("ttl.values", ttlValues); + + Object p3 = prepareData("3", 10); + em.persist(p3); + em.clear(); + + predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + key = ByteBuffer.wrap("3".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + + personNameFound = false; + ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(10, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(10, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(10000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.fail("PERSON_NAME column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + } + + Object p4 = prepareData("4", 10); + em.persist(p4); + em.clear(); + + predicate = new SlicePredicate(); + predicate.setSlice_range(new SliceRange(Bytes.EMPTY.getBytes(), Bytes.EMPTY.getBytes(), true, 10000)); + key = ByteBuffer.wrap("4".getBytes()); + + CassandraCli.client.set_keyspace("KunderaExamples"); + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + + personNameFound = false; + ageFound = false; + + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.assertEquals(10, column.getTtl()); + personNameFound = true; + } + else if (columnName.equals("AGE")) + { + Assert.assertEquals(10, column.getTtl()); + ageFound = true; + } + } + + Assert.assertTrue(personNameFound && ageFound); + Thread.sleep(10000); + + columnOrSuperColumns = CassandraCli.client.get_slice(key, new ColumnParent("PERSONCASSANDRA"), predicate, + ConsistencyLevel.ONE); + for (ColumnOrSuperColumn cosc : columnOrSuperColumns) + { + Column column = cosc.column; + + String columnName = new String(column.getName(), Constants.ENCODING); + if (columnName.equals("PERSON_NAME")) + { + Assert.fail("PERSON_NAME column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + else if (columnName.equals("AGE")) + { + Assert.fail("Age column not deleted even though a TTL of 10 seconds was specified while writing to cassandra."); + } + } + + String deleteQuery = "DELETE from PersonCassandra"; + q = em.createQuery(deleteQuery); + Assert.assertEquals(0, q.executeUpdate()); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTest.java new file mode 100644 index 000000000..8003b8d02 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonCassandraTest.java @@ -0,0 +1,626 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.TypedQuery; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.Column; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.ColumnOrSuperColumn; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.Mutation; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.client.cassandra.thrift.ThriftClient; +import com.impetus.client.crud.PersonCassandra.Day; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Test case to perform simple CRUD operation.(insert, delete, merge, and + * select) + * + * @author kuldeep.mishra + * + * Run this script to create column family in cassandra with indexes. + * create column family PERSON with comparator=UTF8Type and + * column_metadata=[{column_name: PERSON_NAME, validation_class: + * UTF8Type, index_type: KEYS}, {column_name: AGE, validation_class: + * IntegerType, index_type: KEYS}]; + * + */ +public class PersonCassandraTest extends BaseTest +{ + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** The col. */ + private Map col; + + protected Map propertyMap = null; + + protected boolean AUTO_MANAGE_SCHEMA = true; + + protected boolean USE_CQL = false; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + + if (AUTO_MANAGE_SCHEMA) + { + // loadData(); + } + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * On insert cassandra. + * + * @throws Exception + * the exception + */ + @Test + public void onInsertCassandra() throws Exception + { + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + + Query findQuery = em.createQuery("Select p from PersonCassandra p", PersonCassandra.class); + List allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p from PersonCassandra p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p.age from PersonCassandra p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + em.persist(p1); + em.persist(p2); + em.persist(p3); + + PersonCassandra personWithKey = new PersonCassandra(); + personWithKey.setPersonId("111"); + em.persist(personWithKey); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + + em.clear(); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + Assert.assertEquals(Day.THURSDAY, p.getDay()); + + em.clear(); + String qry = "Select p.personId,p.personName from PersonCassandra p where p.personId >= 1"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + + assertFindByName(em, "PersonCassandra", PersonCassandra.class, "vivek", "personName"); + assertFindByNameAndAge(em, "PersonCassandra", PersonCassandra.class, "vivek", "10", "personName"); + assertFindByNameAndAgeGTAndLT(em, "PersonCassandra", PersonCassandra.class, "vivek", "10", "20", "personName"); + assertFindByNameAndAgeBetween(em, "PersonCassandra", PersonCassandra.class, "vivek", "10", "15", "personName"); + assertFindByRange(em, "PersonCassandra", PersonCassandra.class, "1", "2", "personId"); + assertFindWithoutWhereClause(em, "PersonCassandra", PersonCassandra.class); + + // perform merge after query. + for (PersonCassandra person : persons) + { + person.setPersonName("'after merge'"); + em.merge(person); + } + + em.clear(); + + // select rowid test + selectIdQuery(); + + em.clear(); + + p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("'after merge'", p.getPersonName()); + + String updateQuery = "update PersonCassandra p set p.personName=''KK MISHRA'' where p.personId=1"; + q = em.createQuery(updateQuery); + q.executeUpdate(); + + p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("'KK MISHRA'", p.getPersonName()); + + testCountResult(); + // Delete without WHERE clause. + + String deleteQuery = "DELETE from PersonCassandra"; + q = em.createQuery(deleteQuery); + Assert.assertEquals(3, q.executeUpdate()); + + } + + private void testCountResult() + { + Map clientMap = (Map) em.getDelegate(); + ThriftClient tc = (ThriftClient) clientMap.get(SEC_IDX_CASSANDRA_TEST); + tc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + CQLTranslator translator = new CQLTranslator(); + + String query = "select count(*) from " + + translator.ensureCase(new StringBuilder(), "PERSONCASSANDRA").toString(); + Query q = em.createNativeQuery(query, PersonCassandra.class); + List noOfRows = q.getResultList(); + Assert.assertEquals(new Long(3), + PropertyAccessorHelper.getObject(Long.class, ((Column) noOfRows.get(0)).getValue())); + Assert.assertEquals("count", + PropertyAccessorHelper.getObject(String.class, ((Column) noOfRows.get(0)).getName())); + + tc.setCqlVersion(CassandraConstants.CQL_VERSION_2_0); + } + + /** + * On merge cassandra. + * + * @throws Exception + * the exception + */ + @Test + public void onMergeCassandra() throws Exception + { + // CassandraCli.cassandraSetUp(); + // loadData(); + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + em.clear(); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + Assert.assertEquals(Month.APRIL, p.getMonth()); + // modify record. + p.setPersonName("newvivek"); + em.merge(p); + + assertOnMerge(em, "PersonCassandra", PersonCassandra.class, "vivek", "newvivek", "personName"); + } + + @Test + public void onDeleteThenInsertCassandra() throws Exception + { + // CassandraCli.cassandraSetUp(); + // CassandraCli.initClient(); + // loadData(); + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + PersonCassandra p = findById(PersonCassandra.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + em.remove(p); + em.clear(); + + TypedQuery query = em.createQuery("Select p from PersonCassandra p", PersonCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(Month.APRIL, results.get(0).getMonth()); + + p1 = prepareData("1", 10); + em.persist(p1); + + query = em.createQuery("Select p from PersonCassandra p", PersonCassandra.class); + + results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(Month.APRIL, results.get(0).getMonth()); + + } + + @Test + public void onRefreshCassandra() throws Exception + { + // cassandraSetUp(); + // CassandraCli.cassandraSetUp(); + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + CassandraCli.client.set_keyspace("KunderaExamples"); + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + + // Check for contains + Object pp1 = prepareData("1", 10); + Object pp2 = prepareData("2", 20); + Object pp3 = prepareData("3", 15); + Assert.assertTrue(em.contains(pp1)); + Assert.assertTrue(em.contains(pp2)); + Assert.assertTrue(em.contains(pp3)); + + // Check for detach + em.detach(pp1); + em.detach(pp2); + Assert.assertFalse(em.contains(pp1)); + Assert.assertFalse(em.contains(pp2)); + Assert.assertTrue(em.contains(pp3)); + + // Modify value in database directly, refresh and then check PC + em.clear(); + em = emf.createEntityManager(); + Object o1 = em.find(PersonCassandra.class, "1"); + + if (!USE_CQL) + { + // Create Insertion List + List insertionList = new ArrayList(); + List columns = new ArrayList(); + Column column = new Column(); + column.setName(PropertyAccessorFactory.STRING.toBytes("PERSON_NAME")); + column.setValue(PropertyAccessorFactory.STRING.toBytes("Amry")); + column.setTimestamp(System.currentTimeMillis()); + columns.add(column); + Mutation mut = new Mutation(); + mut.setColumn_or_supercolumn(new ColumnOrSuperColumn().setColumn(column)); + insertionList.add(mut); + // Create Mutation Map + Map> columnFamilyValues = new HashMap>(); + columnFamilyValues.put("PERSONCASSANDRA", insertionList); + Map>> mulationMap = new HashMap>>(); + mulationMap.put(ByteBuffer.wrap("1".getBytes()), columnFamilyValues); + CassandraCli.client.batch_mutate(mulationMap, ConsistencyLevel.ONE); + } + else + { + CQLTranslator translator = new CQLTranslator(); + String query = "insert into \"PERSONCASSANDRA\" (key,\"PERSON_NAME\",\"AGE\") values ('1','Amry',10 )"; + CassandraCli.client.execute_cql3_query(ByteBuffer.wrap(query.getBytes()), Compression.NONE, + ConsistencyLevel.ONE); + } + em.refresh(o1); + Object oo1 = em.find(PersonCassandra.class, "1"); + Assert.assertTrue(em.contains(o1)); + Assert.assertEquals("Amry", ((PersonCassandra) oo1).getPersonName()); + } + + /** + * On typed create query + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onTypedQuery() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + TypedQuery query = em.createQuery("Select p from PersonCassandra p", PersonCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(Month.APRIL, results.get(0).getMonth()); + } + + /** + * On typed create query + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onGenericTypedQuery() throws TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + TypedQuery query = em.createQuery("Select p from PersonCassandra p", Object.class); + + List results = query.getResultList(); + Assert.assertNotNull(query); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(PersonCassandra.class, results.get(0).getClass()); + } + + /** + * on invalid typed query. + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Test + public void onInvalidTypedQuery() throws TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + TypedQuery query = null; + try + { + query = em.createQuery("Select p from PersonCassandra p", PersonAuth.class); + Assert.fail("Should have gone to catch block, as it is an invalid scenario!"); + } + catch (IllegalArgumentException iaex) + { + Assert.assertNull(query); + } + } + + @Test + public void onGhostRows() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + // CassandraCli.createKeySpace("KunderaExamples"); + // loadData(); + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + em.clear(); + PersonCassandra person = em.find(PersonCassandra.class, "1"); + em.remove(person); + em.clear(); // just to make sure that not to be picked up from cache. + TypedQuery query = em.createQuery("Select p from PersonCassandra p", PersonCassandra.class); + + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + } + + private void selectIdQuery() + {/* + * String query = "select p.personId from PersonCassandra p"; Query q = + * em.createQuery(query); List results = + * q.getResultList(); Assert.assertNotNull(results); Assert.assertEquals(3, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * + * query = + * "Select p.personId from PersonCassandra p where p.personName = vivek"; + * // // find by name. q = em.createQuery(query); results = + * q.getResultList(); Assert.assertNotNull(results); + * Assert.assertFalse(results.isEmpty()); Assert.assertEquals(3, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * Assert.assertNull(results.get(0).getAge()); + * + * q = em.createQuery( + * "Select p.personId from PersonCassandra p where p.personName = vivek and p.age > " + * + 10); results = q.getResultList(); Assert.assertNotNull(results); + * Assert.assertFalse(results.isEmpty()); Assert.assertEquals(2, + * results.size()); Assert.assertNotNull(results.get(0).getPersonId()); + * Assert.assertNull(results.get(0).getPersonName()); + * Assert.assertNull(results.get(0).getAge()); + */ + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + {/* + * Delete is working, but as row keys are not deleted from cassandra, so + * resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); em.remove(em.find(Person.class, + * "2")); em.remove(em.find(Person.class, "3")); em.close(); emf.close(); + * em = null; emf = null; + */ + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSONCASSANDRA"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("ENUM".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("MONTH_ENUM".getBytes()), "UTF8Type"); + columnDef3.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef3); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSONCASSANDRA")) + { + + CassandraCli.client.system_drop_column_family("PERSONCASSANDRA"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonLuceneCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonLuceneCassandra.java new file mode 100644 index 000000000..f5af9a5b0 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/PersonLuceneCassandra.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "PERSON", schema = "KunderaExamples@luceneCassandraTest") +@IndexCollection(columns = { @com.impetus.kundera.index.Index(name = "personName"), + @com.impetus.kundera.index.Index(name = "age") }) +public class PersonLuceneCassandra +{ + + private static final long serialVersionUID = 6068131491098913126L; + + public static final String UID = "uid"; + + public static final String EID = "eid"; + + public static final String FIRST_NAME = "firstName"; + + public static final String LAST_NAME = "lastName"; + + public static final String CITY = "city"; + + public static final String CREATED = "created"; + + public static final String LAST_MODIFIED = "lastModified"; + + /** The person id. */ + @Id + // @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private String age; + + @Column(name = "AGEss") + private byte[] a; + + @Column(name = "ENUM") + @Enumerated(EnumType.STRING) + private Day day; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public String getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(String age) + { + this.age = age; + } + + /** + * @return the day + */ + public Day getDay() + { + return day; + } + + /** + * @param day + * the day to set + */ + public void setDay(Day day) + { + this.day = day; + } + + enum Day + { + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Token.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Token.java new file mode 100644 index 000000000..f63ddf942 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/Token.java @@ -0,0 +1,62 @@ +package com.impetus.client.crud; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "tokens", schema = "myapp@myapp_pu") +@IndexCollection(columns={@Index(name="tokenName")}) +public class Token +{ + @Id + @Column(name = "token_id") + private String id; + + @ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "client_id") + private TokenClient client; + + @Column + private String tokenName; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public TokenClient getClient() + { + return client; + } + + public void setClient(TokenClient client) + { + this.client = client; + } + + public String getTokenName() + { + return tokenName; + } + + public void setTokenName(String tokenName) + { + this.tokenName = tokenName; + } + + +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TokenClient.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TokenClient.java new file mode 100644 index 000000000..532ba3726 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TokenClient.java @@ -0,0 +1,57 @@ +package com.impetus.client.crud; + +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "client", schema = "myapp@myapp_pu") +public class TokenClient +{ + + @Id + @Column(name = "client_id") + private String id; + + @Column(name = "client_name") + private String clientName; + + @OneToMany(mappedBy = "client", fetch = FetchType.LAZY) + private Set tokens; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getClientName() + { + return clientName; + } + + public void setClientName(String clientName) + { + this.clientName = clientName; + } + + public Set getTokens() + { + return tokens; + } + + public void setTokens(Set tokens) + { + this.tokens = tokens; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUser.java new file mode 100644 index 000000000..9c74a9562 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUser.java @@ -0,0 +1,86 @@ +/** + * + */ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "TUSER", schema = "KunderaExamples@secIdxCassandraTest") +public class TransientUser +{ + + @Id + @Column(name = "USER_ID") + private String userId; + + @Column(name = "USER_NAME") + private String userName; + + @Column(name = "U_NAME") + private transient String uName; + + public TransientUser() + { + // TODO Auto-generated constructor stub + } + + /** + * @return the personId + */ + public String getPersonId() + { + return userId; + } + + /** + * @param personId + * the personId to set + */ + public void setPersonId(String personId) + { + this.userId = personId; + } + + /** + * @return the personName + */ + public String getPersonName() + { + return userName; + } + + /** + * @param personName + * the personName to set + */ + public void setPersonName(String personName) + { + this.userName = personName; + } + + /** + * @return the uName + */ + public String getuName() + { + return uName; + } + + /** + * @param uName + * the uName to set + */ + public void setuName(String uName) + { + this.uName = uName; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUserTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUserTest.java new file mode 100644 index 000000000..9f996c4d3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/TransientUserTest.java @@ -0,0 +1,158 @@ +/** + * + */ +package com.impetus.client.crud; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * @author Kuldeep Mishra + * + */ +public class TransientUserTest +{ + + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + loadData(); + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + @Test + public void test() + { + TransientUser user = new TransientUser(); + user.setPersonId("1233"); + user.setuName("kuldeep"); + user.setPersonName("kk"); + + em.persist(user); + em.clear(); + TransientUser foundUser = em.find(TransientUser.class, "1233"); + Assert.assertNotNull(foundUser); + Assert.assertNull(foundUser.getuName()); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "TUSER"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("USER_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("U_NAME".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("TUSER")) + { + + CassandraCli.client.system_drop_column_family("TUSER"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UpdateDeleteJPQLLiteralTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UpdateDeleteJPQLLiteralTest.java new file mode 100644 index 000000000..6bf7b7302 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UpdateDeleteJPQLLiteralTest.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * Junit test case for Update/Delete via query test. + * + * @author vivek.mishra + * + */ +public class UpdateDeleteJPQLLiteralTest +{ + + private static final String SEC_IDX_CASSANDRA_TEST = "CassandraXmlPropertyTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * Setup + * + * @throws IOException + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + @Before + public void setUp() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + Map propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST, propertyMap); + em = emf.createEntityManager(); + } + + /** + * Test case to demonstrate update via query use case. + * + */ + @Test + public void test() + { + MyTestEntity entity = new MyTestEntity(); + + UUID key = UUID.randomUUID(); + entity.setKey(key); + entity.setUrl("url"); + em.persist(entity); + + // With JPA where clause and update parameter. + String jpql = "update MyTestEntity c set c.url = :url where c.key =:key"; + + Query query = em.createQuery(jpql); + query.setParameter("url", "firstUpdate"); + query.setParameter("key", key); + query.executeUpdate(); + + em.clear(); + + MyTestEntity found = em.find(MyTestEntity.class, key); + + Assert.assertNotNull(found); + Assert.assertEquals("firstUpdate", found.getUrl()); + + // Static where clause with update parameter + jpql = "update MyTestEntity c set c.url = :url where c.key =" + key.toString(); + query = em.createQuery(jpql); + query.setParameter("url", "secondUpdate"); + query.executeUpdate(); + + found = em.find(MyTestEntity.class, key); + + Assert.assertNotNull(found); + Assert.assertEquals("secondUpdate", found.getUrl()); + } + + /** + * JPA String literal test for Select, Update and Delete. + */ + @Test + public void jpaStringLiteralTest() + { + MyTestEntity entity = new MyTestEntity(); + + UUID key = UUID.randomUUID(); + entity.setKey(key); + entity.setUrl("url"); + em.persist(entity); + + String staticJpaQueryEnclosing = "Select e from MyTestEntity e where e.url = 'url'"; + Query query = em.createQuery(staticJpaQueryEnclosing); + + List result = query.getResultList(); + + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + Assert.assertEquals("url", result.get(0).getUrl()); + + String withoutEnclosed = "Select e from MyTestEntity e where e.url = url"; + query = em.createQuery(withoutEnclosed); + + result = query.getResultList(); + + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + Assert.assertEquals("url", result.get(0).getUrl()); + + MyTestEntity found = em.find(MyTestEntity.class, key); + + Assert.assertNotNull(found); + Assert.assertEquals("url", result.get(0).getUrl()); + + found.setUrl("url's"); + + em.merge(found); + + String dynamicQuery = "Select e from MyTestEntity e where e.url = 'url''s'"; + + query = em.createQuery(dynamicQuery); + + result = query.getResultList(); + + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + Assert.assertEquals("url's", result.get(0).getUrl()); + + dynamicQuery = "Select e from MyTestEntity e where e.url = :url"; + query = em.createQuery(dynamicQuery); + query.setParameter("url", "url's"); + + result = query.getResultList(); + + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + Assert.assertEquals("url's", result.get(0).getUrl()); + + // Update by query + // With JPA where clause and update parameter. + String jpql = "update MyTestEntity c set c.url = :url where c.key =" + key.toString(); + query = em.createQuery(jpql); + query.setParameter("url", "updateUrl"); + query.executeUpdate(); + + em.clear(); + + found = em.find(MyTestEntity.class, key); + + Assert.assertNotNull(found); + Assert.assertEquals("updateUrl", found.getUrl()); + + jpql = "update MyTestEntity c set c.url = 'enclosedUrl' where c.key = :key"; + query = em.createQuery(jpql); + query.setParameter("key", key); + query.executeUpdate(); + + found = em.find(MyTestEntity.class, key); + + Assert.assertNotNull(found); + Assert.assertEquals("enclosedUrl", found.getUrl()); + + jpql = "update MyTestEntity c set c.url = 'enclosedUrl''s' where c.key = :key"; + query = em.createQuery(jpql); + query.setParameter("key", key); + query.executeUpdate(); + + found = em.find(MyTestEntity.class, key); + Assert.assertEquals("enclosedUrl's", found.getUrl()); + + // Delete by non column. + + jpql = "Delete c from MyTestEntity c where c.url = :url"; + query = em.createQuery(jpql); + query.setParameter("url", "enclosedUrl's"); + query.executeUpdate(); + + found = em.find(MyTestEntity.class, key); + Assert.assertNull(found); + + } + + @After + public void tearDown() + { + CassandraCli.dropKeySpace("KunderaCassandraXmlTest"); + em.close(); + emf.close(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UserPromoCodeTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UserPromoCodeTest.java new file mode 100644 index 000000000..f990dd878 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/UserPromoCodeTest.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.entity.PromoCode; +import com.impetus.client.entity.Users; +import com.impetus.client.persistence.CassandraCli; + +public class UserPromoCodeTest +{ + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + loadData(); + emf = Persistence.createEntityManagerFactory(SEC_IDX_CASSANDRA_TEST); + em = emf.createEntityManager(); + } + + /** + * On insert cassandra. + * + * @throws Exception + * the exception + */ + @Test + public void onInsertUsers() throws Exception + { + Users u = new Users(); + u.setFirstName("firstname"); + u.setLastName("lastname"); + u.setUserId("1_u"); + + PromoCode promoCode1 = new PromoCode(); + promoCode1.setPromoCodeId("1_p"); + promoCode1.setPromoCodeName("promoname1"); + + u.getPromoCodes().add(promoCode1); + + em.persist(u); + + em.clear(); // to avoid fetch from cache and get from DB. + + Users found = em.find(Users.class, "1_u"); + + Assert.assertNotNull(found); + Assert.assertEquals("firstname", found.getFirstName()); + Assert.assertEquals(1, found.getPromoCodes().size()); + + // add 1 more promo code. + + PromoCode promoCode = new PromoCode(); + promoCode.setPromoCodeId("2_p"); + promoCode.setPromoCodeName("promoname2"); + + found.getPromoCodes().add(promoCode); + em.merge(found); + + em.clear(); // to avoid fetch from cache get from DB. + + found = em.find(Users.class, "1_u"); + + Assert.assertNotNull(found); + Assert.assertEquals("firstname", found.getFirstName()); + Assert.assertEquals(2, found.getPromoCodes().size()); + + // Delete + em.remove(found); + + found = em.find(Users.class, "1_u"); + + Assert.assertNull(found); + + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "users"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setColumn_type("Super"); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("users")) + { + + CassandraCli.client.system_drop_column_family("users"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } + + @After + + public void tearDown() + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/AddressBatch.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/AddressBatch.java new file mode 100644 index 000000000..d35e37845 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/AddressBatch.java @@ -0,0 +1,78 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.crud.batch; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Entity class for batch operation + * + * @author amresh.singh + */ + +@Entity +@Table(name = "ADDRESS_BATCH", schema = "KunderaExamples@batchTestSizeTwenty") +@IndexCollection(columns = { @Index(name = "STREET") }) +public class AddressBatch +{ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The person name. */ + @Column(name = "STREET") + private String street; + + /** + * @return the addressId + */ + public String getAddressId() + { + return addressId; + } + + /** + * @param addressId + * the addressId to set + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * @param street + * the street to set + */ + public void setStreet(String street) + { + this.street = street; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorMixedTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorMixedTest.java new file mode 100644 index 000000000..0f1b89e62 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorMixedTest.java @@ -0,0 +1,249 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.crud.batch; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * Test case for more than one entities persisted in the same batch + * + * @author amresh.singh + */ +public class CassandraBatchProcessorMixedTest +{ + + private static final String CF_ADDRESS_BATCH = "ADDRESS_BATCH"; + + private static final String CF_PERSON_BATCH = "PERSON_BATCH"; + + private static final String KEYSPACE_KUNDERA_EXAMPLES = "KunderaExamples"; + + private static final String PERSISTENCE_UNIT = "batchTestSizeTwenty"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + @Before + public void setUp() throws Exception + { + + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(KEYSPACE_KUNDERA_EXAMPLES); + loadData(); + + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + em = emf.createEntityManager(); + } + + @Test + public void onBatch() + { + List persons = preparePersonData(10); + List addresses = prepareAddressData(10); + + // Insert Persons + for (PersonBatch person : persons) + { + em.persist(person); + } + + // Insert Addresses + for (AddressBatch address : addresses) + { + em.persist(address); + } + + // flush all on close. + // explicit flush on close + em.clear(); + em.close(); + + em = emf.createEntityManager(); + + // Query on Persons + String personsQueryStr = " Select p from PersonBatch p"; + Query personsQuery = em.createQuery(personsQueryStr); + List allPersons = personsQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertEquals(10, allPersons.size()); + + // Query on Addresses + String addressQueryStr = " Select a from AddressBatch a"; + Query addressQuery = em.createQuery(addressQueryStr); + List allAddresses = addressQuery.getResultList(); + Assert.assertNotNull(allAddresses); + Assert.assertEquals(10, allAddresses.size()); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace(KEYSPACE_KUNDERA_EXAMPLES); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + + CfDef user_Def = new CfDef(); + user_Def.name = CF_PERSON_BATCH; + user_Def.keyspace = KEYSPACE_KUNDERA_EXAMPLES; + user_Def.setComparator_type("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("AGEss".getBytes()), "BytesType"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + + CfDef address_Def = new CfDef(); + address_Def.name = CF_ADDRESS_BATCH; + address_Def.keyspace = KEYSPACE_KUNDERA_EXAMPLES; + address_Def.setComparator_type("UTF8Type"); + address_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDefStreet = new ColumnDef(ByteBuffer.wrap("STREET".getBytes()), "UTF8Type"); + columnDefStreet.index_type = IndexType.KEYS; + address_Def.addToColumn_metadata(columnDefStreet); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + cfDefs.add(address_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace(KEYSPACE_KUNDERA_EXAMPLES); + CassandraCli.client.set_keyspace(KEYSPACE_KUNDERA_EXAMPLES); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase(CF_PERSON_BATCH)) + { + CassandraCli.client.system_drop_column_family(CF_PERSON_BATCH); + } + else if (cfDef1.getName().equalsIgnoreCase(CF_ADDRESS_BATCH)) + { + CassandraCli.client.system_drop_column_family(CF_ADDRESS_BATCH); + } + } + CassandraCli.client.system_add_column_family(user_Def); + CassandraCli.client.system_add_column_family(address_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(KEYSPACE_KUNDERA_EXAMPLES, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(KEYSPACE_KUNDERA_EXAMPLES); + + } + + private List preparePersonData(Integer noOfRecords) + { + List persons = new ArrayList(); + for (int i = 1; i <= noOfRecords; i++) + { + PersonBatch o = new PersonBatch(); + o.setPersonId(i + ""); + o.setPersonName("Name " + i); + o.setAge(10); + persons.add(o); + } + return persons; + } + + private List prepareAddressData(Integer noOfRecords) + { + List addresses = new ArrayList(); + for (int i = 1; i <= noOfRecords; i++) + { + AddressBatch o = new AddressBatch(); + o.setAddressId(i + ""); + o.setStreet("My Street " + i); + addresses.add(o); + } + return addresses; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorTest.java new file mode 100644 index 000000000..7aa7cb80f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/CassandraBatchProcessorTest.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.batch; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.persistence.api.Batcher; + +/** + * Batch processing test case for cassandra. + * + * @author vivek.mishra + * + */ +public class CassandraBatchProcessorTest +{ + + /** + * + */ + private static final String PERSISTENCE_UNIT = "secIdxBatchTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + protected boolean AUTO_MANAGE_SCHEMA = true; + + protected boolean USE_CQL = false; + + protected Map propertyMap = null; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + + // cassandraSetUp(); + CassandraCli.cassandraSetUp(); + // CassandraCli.initClient(); + CassandraCli.createKeySpace("KunderaExamples"); + if (AUTO_MANAGE_SCHEMA) + { + loadData(); + } + + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + propertyMap.put("kundera.batch.size", "5"); + } + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT, propertyMap); + em = emf.createEntityManager(); + } + + @Test + public void onBatch() + { + int counter = 0; + List rows = prepareData(10); + for (PersonBatchCassandraEntity entity : rows) + { + em.persist(entity); + + // check for implicit flush. + if (++counter == 5) + { + Map clients = (Map) em.getDelegate(); + + Batcher client = (Batcher) clients.get(PERSISTENCE_UNIT); + Assert.assertEquals(5, client.getBatchSize()); + em.clear(); + for (int i = 0; i < 5; i++) + { + + // assert on each batch size record + Assert.assertNotNull(em.find(PersonBatchCassandraEntity.class, rows.get(i).getPersonId())); + + // as batch size is 5. + Assert.assertNull(em.find(PersonBatchCassandraEntity.class, rows.get(6).getPersonId())); + } + // means implicit flush must happen + } + } + + // flush all on close. + // explicit flush on close + em.clear(); + em.close(); + + em = emf.createEntityManager(); + + String sql = " Select p from PersonBatchCassandraEntity p"; + Query query = em.createQuery(sql); + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(10, results.size()); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + CassandraCli.dropKeySpace("KunderaExamples"); + } + + /** + * Load cassandra specific data. + * + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + private void loadData() throws TException, InvalidRequestException, UnavailableException, TimedOutException, + SchemaDisagreementException + { + + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "PERSON_BATCH"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + try + { + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSON_BATCH")) + { + + CassandraCli.client.system_drop_column_family("PERSON_BATCH"); + + } + } + CassandraCli.client.system_add_column_family(user_Def); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } + + private List prepareData(Integer noOfRecords) + { + List persons = new ArrayList(); + for (int i = 1; i <= noOfRecords; i++) + { + PersonBatchCassandraEntity o = new PersonBatchCassandraEntity(); + o.setPersonId(i + ""); + o.setPersonName("vivek" + i); + o.setAge(10); + persons.add(o); + } + + return persons; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatch.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatch.java new file mode 100644 index 000000000..670162d7c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatch.java @@ -0,0 +1,128 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.crud.batch; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Entity class for Person in Batch operation + * + * @author amresh.singh + */ +@Entity +@Table(name = "PERSON_BATCH", schema = "KunderaExamples@batchTestSizeTwenty") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class PersonBatch +{ + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatchCassandraEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatchCassandraEntity.java new file mode 100644 index 000000000..373b9066b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/batch/PersonBatchCassandraEntity.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.batch; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON_BATCH", schema = "KunderaExamples@secIdxBatchTest") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class PersonBatchCassandraEntity +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPost.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPost.java new file mode 100644 index 000000000..dbc98ea60 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPost.java @@ -0,0 +1,173 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.collection; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Entity class for Blog post + * @author amresh.singh + */ +@Entity +@Table(name="blog_posts", schema="KunderaExamples@secIdxCassandraTest") +@IndexCollection(columns = { @Index(name = "body")}) +public class BlogPost +{ + @Id + @Column(name="post_id") + private int postId; + + //Body of the post + @Column(name="body") + private String body; + + //Useful tags specified by author + @ElementCollection + @Column(name="tags") + private Set tags; + + //List of user IDs who liked this blog post + @ElementCollection + @Column(name="liked_by") + private List likedBy; + + //User IDs and their respective comments on this blog + @ElementCollection + @Column(name="comments") + private Map comments; + + /** + * @return the postId + */ + public int getPostId() + { + return postId; + } + + /** + * @param postId the postId to set + */ + public void setPostId(int postId) + { + this.postId = postId; + } + + /** + * @return the body + */ + public String getBody() + { + return body; + } + + /** + * @param body the body to set + */ + public void setBody(String body) + { + this.body = body; + } + + /** + * @return the tags + */ + public Set getTags() + { + return tags; + } + + /** + * @param tags the tags to set + */ + public void setTags(Set tags) + { + this.tags = tags; + } + + /** + * @return the likedBy + */ + public List getLikedBy() + { + return likedBy; + } + + /** + * @param likedBy the likedBy to set + */ + public void setLikedBy(List likedBy) + { + this.likedBy = likedBy; + } + + /** + * @return the comments + */ + public Map getComments() + { + return comments; + } + + /** + * @param comments the comments to set + */ + public void setComments(Map comments) + { + this.comments = comments; + } + + public void addTag(String tag) + { + if(tags == null) + { + tags = new HashSet(); + } + tags.add(tag); + } + + public void addLikedBy(int likedByUserId) + { + if(likedBy == null) + { + likedBy = new ArrayList(); + } + likedBy.add(likedByUserId); + } + + public void addComment(int userId, String comment) + { + if(comments == null) + { + comments = new HashMap(); + } + comments.put(userId, comment); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPostTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPostTest.java new file mode 100644 index 000000000..b418e585c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/collection/BlogPostTest.java @@ -0,0 +1,519 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.collection; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; + +/** + * Test case for Storing and retrieving Blog posts. 1. Validates correct + * functioning of Element collection for basic types 2. Checks all types of + * collection (Set, Map, List) + * + * @author amresh.singh + */ +public class BlogPostTest +{ + EntityManagerFactory emf; + + EntityManager em; + + String persistenceUnit = "secIdxCassandraTest"; + + private boolean RUN_IN_EMBEDDED_MOODE = true; + private boolean AUTO_MANAGE_SCHEMA = true; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MOODE) + { + CassandraCli.cassandraSetUp(); + } + + if (AUTO_MANAGE_SCHEMA) + { + + createKeyspace(); + createColumnFamily(); + } + + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + em.setProperty(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + } + + + + // @Test + public void dummyTest() + { + + } + + @Test + public void testCRUD() + { + // Insert records + BlogPost p1 = prepareBlogPost1(); + BlogPost p2 = prepareBlogPost2(); + + em.persist(p1); + em.persist(p2); + + // Find records by ID + em.clear(); + BlogPost pp1 = em.find(BlogPost.class, 1); + BlogPost pp2 = em.find(BlogPost.class, 2); + + assertPost1(pp1); + assertPost2(pp2); + + // Update records + modifyBlogPost1(pp1); + modifyBlogPost2(pp2); + + em.merge(pp1); + em.merge(pp2); + + em.clear(); + pp1 = em.find(BlogPost.class, 1); + pp2 = em.find(BlogPost.class, 2); + + assertUpdatedPost1(pp1); + assertUpdatedPost2(pp2); + + // Remove records + em.remove(pp1); + em.remove(pp2); + + em.clear(); + pp1 = em.find(BlogPost.class, 1); + pp2 = em.find(BlogPost.class, 2); + + Assert.assertNull(pp1); + Assert.assertNull(pp2); + } + + @Test + public void testJPAQuery() + { + // Insert records + BlogPost p1 = prepareBlogPost1(); + BlogPost p2 = prepareBlogPost2(); + + em.persist(p1); + em.persist(p2); + + // Select All query + Query q = em.createQuery("Select p from BlogPost p"); + List allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(2, allPosts.size()); + assertPost1(allPosts.get(0)); + assertPost2(allPosts.get(1)); + + // Search over Row ID + q = em.createQuery("Select p from BlogPost p where p.postId=:postId"); + q.setParameter("postId", 1); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertPost1(allPosts.get(0)); + + // Search over Body column + q = em.createQuery("Select p from BlogPost p where p.body=:body"); + q.setParameter("body", "Kundera - Knight in the shining armor!"); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertPost2(allPosts.get(0)); + + // Update Query + q = em.createQuery("update BlogPost p set p.body=:body,p.tags=:tags,p.likedBy=:likedBy,p.comments=:comments where p.postId=1"); + modifyBlogPost1(p1); + q.setParameter("body", p1.getBody()); + q.setParameter("tags", p1.getTags()); + q.setParameter("likedBy", p1.getLikedBy()); + q.setParameter("comments", p1.getComments()); + int updatedRecords = q.executeUpdate(); + Assert.assertEquals(1, updatedRecords); + + em.clear(); + q = em.createQuery("Select p from BlogPost p where p.postId=:postId"); + q.setParameter("postId", 1); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertUpdatedPost1(allPosts.get(0)); + + // Delete Query + q = em.createQuery("DELETE from BlogPost"); + int deleteCount = q.executeUpdate(); + Assert.assertEquals(2, deleteCount); + + em.clear(); + q = em.createQuery("Select p from BlogPost p"); + allPosts = q.getResultList(); + Assert.assertTrue(allPosts == null || allPosts.isEmpty()); + } + + @Test + public void testNativeQuery() + { + // Insert records + BlogPost p1 = prepareBlogPost1(); + BlogPost p2 = prepareBlogPost2(); + + em.persist(p1); + em.persist(p2); + + // Select All query + Query q = em.createNativeQuery("select * from blog_posts", BlogPost.class); + List allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(2, allPosts.size()); + assertPost1(allPosts.get(0)); + assertPost2(allPosts.get(1)); + + // Search over a column + q = em.createNativeQuery("select * from blog_posts where body='Working with MongoDB using Kundera'", + BlogPost.class); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertPost1(allPosts.get(0)); + + // Updating set, list and map for Blog Post 1 + q = em.createNativeQuery("update blog_posts set body = 'Updated body 1' where post_id = 1", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set tags = tags + {'new tag 1'} where post_id = 1", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set liked_by = liked_by - [111] where post_id = 1", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set comments = comments + {888:'New comment 1'} where post_id = 1", + BlogPost.class); + q.executeUpdate(); + + q = em.createNativeQuery("select * from blog_posts where post_id = 1", BlogPost.class); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertUpdatedPost1(allPosts.get(0)); + + // Updating set, list and map for Blog Post 2 + q = em.createNativeQuery("update blog_posts set body = 'Updated body 2' where post_id = 2", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set tags = tags + {'new tag 2'} where post_id = 2", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set liked_by = liked_by - [444] where post_id = 2", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("update blog_posts set comments = comments + {999:'New comment 2'} where post_id = 2", + BlogPost.class); + q.executeUpdate(); + + q = em.createNativeQuery("select * from blog_posts where post_id = 2", BlogPost.class); + allPosts = q.getResultList(); + Assert.assertNotNull(allPosts); + Assert.assertFalse(allPosts.isEmpty()); + Assert.assertEquals(1, allPosts.size()); + assertUpdatedPost2(allPosts.get(0)); + + // Delete all posts + q = em.createNativeQuery("delete from blog_posts where post_id = 1", BlogPost.class); + q.executeUpdate(); + q = em.createNativeQuery("delete from blog_posts where post_id = 2", BlogPost.class); + q.executeUpdate(); + + q = em.createNativeQuery("select * from blog_posts", BlogPost.class); + allPosts = q.getResultList(); + Assert.assertTrue(allPosts == null || allPosts.isEmpty()); + } + + private BlogPost prepareBlogPost1() + { + BlogPost p1 = new BlogPost(); + p1.setPostId(1); + p1.setBody("Working with MongoDB using Kundera"); + + p1.addTag("nosql"); + p1.addTag("kundera"); + p1.addTag("mongo"); + + p1.addLikedBy(111); + p1.addLikedBy(222); + + p1.addComment(111, "What a post!"); + p1.addComment(222, "I am getting NPE on line no. 145"); + p1.addComment(333, "My hobby is to spam blogs"); + return p1; + } + + private BlogPost prepareBlogPost2() + { + BlogPost p2 = new BlogPost(); + p2.setPostId(2); + p2.setBody("Kundera - Knight in the shining armor!"); + + p2.addTag("nosql"); + p2.addTag("cassandra"); + p2.addTag("kundera"); + p2.addTag("jpa"); + + p2.addLikedBy(333); + p2.addLikedBy(444); + p2.addLikedBy(555); + + p2.addComment(333, "Great work"); + p2.addComment(555, "Doesn't work on my machine"); + p2.addComment(777, "Wanna buy medicines from my store?"); + return p2; + } + + private void modifyBlogPost1(BlogPost p) + { + p.setBody("Updated body 1"); + p.getTags().add("new tag 1"); + p.getLikedBy().remove(0); + p.addComment(888, "New comment 1"); + } + + private void modifyBlogPost2(BlogPost p) + { + p.setBody("Updated body 2"); + p.getTags().add("new tag 2"); + p.getLikedBy().remove(1); + p.addComment(999, "New comment 2"); + } + + private void assertPost1(BlogPost p) + { + Assert.assertNotNull(p); + Assert.assertEquals(1, p.getPostId()); + Assert.assertEquals("Working with MongoDB using Kundera", p.getBody()); + + Assert.assertNotNull(p.getTags()); + Assert.assertFalse(p.getTags().isEmpty()); + Assert.assertEquals(3, p.getTags().size()); + for (String tag : p.getTags()) + { + Assert.assertTrue(tag.equals("nosql") || tag.equals("kundera") || tag.equals("mongo")); + } + + Assert.assertNotNull(p.getLikedBy()); + Assert.assertFalse(p.getLikedBy().isEmpty()); + Assert.assertEquals(2, p.getLikedBy().size()); + for (int likedUserId : p.getLikedBy()) + { + Assert.assertTrue(likedUserId == 111 || likedUserId == 222); + } + + Assert.assertNotNull(p.getComments()); + Assert.assertFalse(p.getComments().isEmpty()); + Assert.assertEquals(3, p.getComments().size()); + for (int commentedBy : p.getComments().keySet()) + { + String commentText = p.getComments().get(commentedBy); + Assert.assertTrue(commentedBy == 111 || commentedBy == 222 || commentedBy == 333); + Assert.assertTrue(commentText.equals("What a post!") + || commentText.equals("I am getting NPE on line no. 145") + || commentText.equals("My hobby is to spam blogs")); + } + } + + private void assertPost2(BlogPost p) + { + Assert.assertNotNull(p); + Assert.assertEquals(2, p.getPostId()); + Assert.assertEquals("Kundera - Knight in the shining armor!", p.getBody()); + + Assert.assertNotNull(p.getTags()); + Assert.assertFalse(p.getTags().isEmpty()); + Assert.assertEquals(4, p.getTags().size()); + for (String tag : p.getTags()) + { + Assert.assertTrue(tag.equals("nosql") || tag.equals("cassandra") || tag.equals("kundera") + || tag.equals("jpa")); + } + + Assert.assertNotNull(p.getLikedBy()); + Assert.assertFalse(p.getLikedBy().isEmpty()); + Assert.assertEquals(3, p.getLikedBy().size()); + for (int likedUserId : p.getLikedBy()) + { + Assert.assertTrue(likedUserId == 333 || likedUserId == 444 || likedUserId == 555); + } + + Assert.assertNotNull(p.getComments()); + Assert.assertFalse(p.getComments().isEmpty()); + Assert.assertEquals(3, p.getComments().size()); + for (int commentedBy : p.getComments().keySet()) + { + String commentText = p.getComments().get(commentedBy); + Assert.assertTrue(commentedBy == 333 || commentedBy == 555 || commentedBy == 777); + Assert.assertTrue(commentText.equals("Great work") || commentText.equals("Doesn't work on my machine") + || commentText.equals("Wanna buy medicines from my store?")); + } + } + + private void assertUpdatedPost1(BlogPost p) + { + Assert.assertNotNull(p); + Assert.assertEquals(1, p.getPostId()); + Assert.assertEquals("Updated body 1", p.getBody()); + + Assert.assertNotNull(p.getTags()); + Assert.assertFalse(p.getTags().isEmpty()); + Assert.assertEquals(4, p.getTags().size()); + for (String tag : p.getTags()) + { + Assert.assertTrue(tag.equals("nosql") || tag.equals("kundera") || tag.equals("mongo") + || tag.equals("new tag 1")); + } + + Assert.assertNotNull(p.getLikedBy()); + Assert.assertFalse(p.getLikedBy().isEmpty()); + Assert.assertEquals(1, p.getLikedBy().size()); + for (int likedUserId : p.getLikedBy()) + { + Assert.assertTrue(likedUserId == 222); + } + + Assert.assertNotNull(p.getComments()); + Assert.assertFalse(p.getComments().isEmpty()); + Assert.assertEquals(4, p.getComments().size()); + for (int commentedBy : p.getComments().keySet()) + { + String commentText = p.getComments().get(commentedBy); + Assert.assertTrue(commentedBy == 111 || commentedBy == 222 || commentedBy == 333 || commentedBy == 888); + Assert.assertTrue(commentText.equals("What a post!") + || commentText.equals("I am getting NPE on line no. 145") + || commentText.equals("My hobby is to spam blogs") || commentText.equals("New comment 1")); + } + + } + + private void assertUpdatedPost2(BlogPost p) + { + Assert.assertNotNull(p); + Assert.assertEquals(2, p.getPostId()); + Assert.assertEquals("Updated body 2", p.getBody()); + + Assert.assertNotNull(p.getTags()); + Assert.assertFalse(p.getTags().isEmpty()); + Assert.assertEquals(5, p.getTags().size()); + for (String tag : p.getTags()) + { + Assert.assertTrue(tag.equals("nosql") || tag.equals("cassandra") || tag.equals("kundera") + || tag.equals("jpa") || tag.equals("new tag 2")); + } + + Assert.assertNotNull(p.getLikedBy()); + Assert.assertFalse(p.getLikedBy().isEmpty()); + Assert.assertEquals(2, p.getLikedBy().size()); + for (int likedUserId : p.getLikedBy()) + { + Assert.assertTrue(likedUserId == 333 || likedUserId == 555); + } + + Assert.assertNotNull(p.getComments()); + Assert.assertFalse(p.getComments().isEmpty()); + Assert.assertEquals(4, p.getComments().size()); + for (int commentedBy : p.getComments().keySet()) + { + String commentText = p.getComments().get(commentedBy); + Assert.assertTrue(commentedBy == 333 || commentedBy == 555 || commentedBy == 777 || commentedBy == 999); + Assert.assertTrue(commentText.equals("Great work") || commentText.equals("Doesn't work on my machine") + || commentText.equals("Wanna buy medicines from my store?") || commentText.equals("New comment 2")); + } + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + if (em != null && em.isOpen()) + { + em.close(); + } + if (emf != null && emf.isOpen()) + { + emf.close(); + } + + if (AUTO_MANAGE_SCHEMA) + { + CassandraCli.executeCqlQuery("USE \"KunderaExamples\""); + CassandraCli.executeCqlQuery("TRUNCATE blog_posts"); + CassandraCli.executeCqlQuery("DROP TABLE blog_posts"); + CassandraCli.executeCqlQuery("DROP KEYSPACE \"KunderaExamples\""); + } + + } + + private void createColumnFamily() + { + try + { + CassandraCli.executeCqlQuery("USE \"KunderaExamples\""); + CassandraCli + .executeCqlQuery("CREATE TABLE blog_posts (post_id int PRIMARY KEY, body text, tags set, liked_by list, comments map)"); + CassandraCli.executeCqlQuery("CREATE INDEX ON blog_posts(body)"); + } + catch (Exception e) + { + } + } + + private void createKeyspace() + { + try + { + CassandraCli + .executeCqlQuery("CREATE KEYSPACE \"KunderaExamples\" WITH replication = {'class':'SimpleStrategy','replication_factor':3}"); + } + catch (Exception e) + { + + } + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CQLTranslatorTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CQLTranslatorTest.java new file mode 100644 index 000000000..1118e1df3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CQLTranslatorTest.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.thrift.CQLTranslator; +import com.impetus.client.cassandra.thrift.CQLTranslator.TranslationType; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * JUnit for CQL translator test + * + * @author vivek.mishra + * + */ +public class CQLTranslatorTest +{ + private EntityManagerFactory emf; + + private static final Logger logger = LoggerFactory.getLogger(CassandraCompositeTypeTest.class); + + private static final String KEYSPACE = "CompositeCassandra"; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.dropKeySpace(KEYSPACE); + CassandraCli.cassandraSetUp(); + emf = Persistence.createEntityManagerFactory("composite_pu"); + } + + @Test + public void testPrepareColumns() + { + logger.info("On prepare columns."); + CQLTranslator translator = new CQLTranslator(); + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + CassandraPrimeUser user = new CassandraPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(CassandraPrimeUser.class); + String translatedSql = translator + .prepareColumnOrColumnValues(user, entityMetadata, TranslationType.VALUE, null).get( + TranslationType.VALUE); + String columnAsCsv = "'mevivs',1," + timeLineId + ",'my first tweet','" + currentDate.getTime() + "'"; + Assert.assertEquals(columnAsCsv, translatedSql); + } + + @Test + public void testGetKeyword() + { + CQLTranslator translator = new CQLTranslator(); + Assert.assertEquals("read_repair_chance", translator.getKeyword(CassandraConstants.READ_REPAIR_CHANCE)); + Assert.assertEquals("dclocal_read_repair_chance", translator.getKeyword(CassandraConstants.DCLOCAL_READ_REPAIR_CHANCE)); + Assert.assertEquals("bloom_filter_fp_chance", translator.getKeyword(CassandraConstants.BLOOM_FILTER_FP_CHANCE)); + Assert.assertEquals("compaction_strategy_class", translator.getKeyword(CassandraConstants.COMPACTION_STRATEGY)); + Assert.assertEquals("bloom_filter_fp_chance", translator.getKeyword(CassandraConstants.BLOOM_FILTER_FP_CHANCE)); + Assert.assertEquals("replicate_on_write", translator.getKeyword(CassandraConstants.REPLICATE_ON_WRITE)); + Assert.assertEquals("caching", translator.getKeyword(CassandraConstants.CACHING)); + Assert.assertEquals("comment", translator.getKeyword(CassandraConstants.COMMENT)); + Assert.assertEquals("gc_grace_seconds", translator.getKeyword(CassandraConstants.GC_GRACE_SECONDS)); + + } + + @After + public void tearDown() + { + CassandraCli.dropKeySpace(KEYSPACE); + emf.close(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompositeTypeTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompositeTypeTest.java new file mode 100644 index 000000000..1920e71dc --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompositeTypeTest.java @@ -0,0 +1,546 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.nio.ByteBuffer; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.compositeType.CassandraPrimeUser.NickName; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Junit test case for Compound/Composite key. + * + * @author vivek.mishra + * + */ + +public class CassandraCompositeTypeTest +{ + + /** + * + */ + private static final String PERSISTENCE_UNIT = "composite_pu"; + + private EntityManagerFactory emf; + + /** The Constant logger. */ + private static final Logger logger = LoggerFactory.getLogger(CassandraCompositeTypeTest.class); + + // @Rule + // public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new + // CSVSummaryReportModule(), + // new HtmlReportModule() }); + + private Date currentDate = new Date(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } + + @Test + public void onAddColumn() throws Exception + { + // cql script is not adding "tweetBody", kundera.ddl.auto.update will + // add it. + String cql_Query = "create columnfamily \"CompositeUser\" (\"userId\" text, \"tweetId\" int, \"timeLineId\" uuid, " + + " \"tweetDate\" timestamp, PRIMARY KEY(\"userId\",\"tweetId\",\"timeLineId\"))"; + + executeScript(cql_Query); + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + onCRUD(em, key); + em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + CassandraPrimeUser result = em.find(CassandraPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("After merge", result.getTweetBody()); // assertion + // of newly + // added + // tweet body + em.remove(result); + + em.flush(); + em.close(); + em =emf.createEntityManager(); + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + result = em.find(CassandraPrimeUser.class, key); + Assert.assertNull(result); + + em.close(); + } + + @Test + public void onAlterColumnType() throws Exception + { + // Here tweetDate is of type "int". On update will be changed to + // timestamp. + + String cql_Query = "create columnfamily \"CompositeUser\" (\"userId\" text, \"tweetId\" int, \"timeLineId\" uuid, " + + " \"tweetDate\" int, PRIMARY KEY(\"userId\",\"tweetId\",\"timeLineId\"))"; + executeScript(cql_Query); + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + EntityManager em = emf.createEntityManager(); + UUID timeLineId = UUID.randomUUID(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + onCRUD(em, key); + em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + CassandraPrimeUser result = em.find(CassandraPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); // assertion + // of + // changed + // tweetDate. + em.remove(result); + em.flush(); + em.close(); + em =emf.createEntityManager(); + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + result = em.find(CassandraPrimeUser.class, key); + Assert.assertNull(result); + + em.close(); + } + + @Test + public void onQuery() + { + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + CassandraPrimeUser user = new CassandraPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.flush(); // optional,just to clear persistence cache. + + em.clear(); + + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + final String noClause = "Select u from CassandraPrimeUser u"; + + final String withFirstCompositeColClause = "Select u from CassandraPrimeUser u where u.key.userId = :userId"; + + // secondary index support over compound key is not enabled in cassandra + // composite keys yet. DO NOT DELETE/UNCOMMENT. + + // final String withClauseOnNoncomposite = + // "Select u from CassandraPrimeUser u where u.tweetDate = ?1"; + // + + final String withSecondCompositeColClause = "Select u from CassandraPrimeUser u where u.key.tweetId = :tweetId"; + final String withBothCompositeColClause = "Select u from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId"; + final String withAllCompositeColClause = "Select u from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + final String withLastCompositeColGTClause = "Select u from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId >= :timeLineId"; + + final String withSelectiveCompositeColClause = "Select u.key from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + + // query over 1 composite and 1 non-column + + // query with no clause. + Query q = em.createQuery(noClause); + List results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withFirstCompositeColClause); + q.setParameter("userId", "mevivs"); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withSecondCompositeColClause); + q.setParameter("tweetId", 1); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withBothCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withLastCompositeColGTClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + + Assert.assertEquals(1, results.size()); + + // Query with composite key with selective clause. + q = em.createQuery(withSelectiveCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertNull(results.get(0).getTweetBody()); + + final String selectiveColumnTweetBodyWithAllCompositeColClause = "Select u.tweetBody from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + // Query for selective column tweetBody with composite key clause. + q = em.createQuery(selectiveColumnTweetBodyWithAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("my first tweet", results.get(0).getTweetBody()); + Assert.assertNull(results.get(0).getTweetDate()); + + final String selectiveColumnTweetDateWithAllCompositeColClause = "Select u.tweetDate from CassandraPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + // Query for selective column tweetDate with composite key clause. + q = em.createQuery(selectiveColumnTweetDateWithAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(currentDate.getTime(), results.get(0).getTweetDate().getTime()); + Assert.assertNull(results.get(0).getTweetBody()); + + final String withCompositeKeyClause = "Select u from CassandraPrimeUser u where u.key = :key"; + // Query with composite key clause. + q = em.createQuery(withCompositeKeyClause); + q.setParameter("key", key); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + em.remove(user); + + em.clear();// optional,just to clear persistence cache. + } + + @Test + public void onNamedQueryTest() + { + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + updateNamed(); + deleteNamed(); + } + + @Test + public void onLimit() + { + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + CassandraPrimeUser user1 = new CassandraPrimeUser(key); + user1.setTweetBody("my first tweet"); + user1.setTweetDate(currentDate); + em.persist(user1); + + key = new CassandraCompoundKey("mevivs", 2, timeLineId); + CassandraPrimeUser user2 = new CassandraPrimeUser(key); + user2.setTweetBody("my first tweet"); + user2.setTweetDate(currentDate); + em.persist(user2); + + key = new CassandraCompoundKey("mevivs", 3, timeLineId); + CassandraPrimeUser user3 = new CassandraPrimeUser(key); + user3.setTweetBody("my first tweet"); + user3.setTweetDate(currentDate); + em.persist(user3); + + em.flush(); + + // em.clear(); // optional,just to clear persistence cache. + + // em = emf.createEntityManager(); + em.clear(); + + final String noClause = "Select u from CassandraPrimeUser u"; + Query q = em.createQuery(noClause); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + // With limit + q = em.createQuery(noClause); + q.setMaxResults(2); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + } + + @Test + public void onBatchInsert() + { + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + long t1 = System.currentTimeMillis(); + for (int i = 0; i < 500; i++) + { + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", i, timeLineId); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + CassandraPrimeUser user = new CassandraPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + } + long t2 = System.currentTimeMillis(); + System.out.println("Total time taken = " + (t2 - t1)); + + em.clear(); + + CassandraPrimeUser u = em.find(CassandraPrimeUser.class, new CassandraCompoundKey("mevivs", 499, timeLineId)); + Assert.assertNotNull(u); + } + + /** + * CompositeUserDataType + * + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + CassandraCli.client.execute_cql3_query(ByteBuffer.wrap("use \"CompositeCassandra\"".getBytes()), + Compression.NONE, ConsistencyLevel.ONE); + CassandraCli.client.execute_cql3_query(ByteBuffer.wrap("truncate \"CompositeUser\"".getBytes()), + Compression.NONE, ConsistencyLevel.ONE); + CassandraCli.dropKeySpace("CompositeCassandra"); + } + + // DO NOT DELETE IT!! though it is automated with schema creation option. + /** + * create column family script for compound key. + */ + private void executeScript(final String cql) + { + CassandraCli.createKeySpace("CompositeCassandra"); + try + { + CassandraCli.getClient().set_keyspace("CompositeCassandra"); + CassandraCli.executeCqlQuery(cql); + } + catch (InvalidRequestException e) + { + logger.error(e.getMessage()); + } + catch (TException e) + { + logger.error(e.getMessage()); + } + } + + /** + * CRUD over Compound primary Key. + */ + + private void onCRUD(final EntityManager em, CassandraCompoundKey key) + { + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + CassandraPrimeUser user = new CassandraPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + user.setNickName(NickName.KK); + em.persist(user); + em.flush(); + + // em.clear(); // optional,just to clear persistence cache. + + // em = emf.createEntityManager(); + em.clear(); + + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + CassandraPrimeUser result = em.find(CassandraPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("my first tweet", result.getTweetBody()); + // Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + Assert.assertEquals(NickName.KK, result.getNickName()); + Assert.assertEquals(NickName.KK.name(), result.getNickName().name()); + + em.clear();// optional,just to clear persistence cache. + + user.setTweetBody("After merge"); + em.merge(user); + em.close();// optional,just to clear persistence cache. + + EntityManager em1 = emf.createEntityManager(); + // em = emf.createEntityManager(); + clients = (Map) em1.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + result = em1.find(CassandraPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("After merge", result.getTweetBody()); + // Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + + // deleting composite + em1.clear(); // optional,just to clear persistence cache. + // em.close();// optional,just to clear persistence cache. + + } + + /** + * Update by Named Query. + * + * @return + */ + private void updateNamed() + { + EntityManager em = emf.createEntityManager(); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + UUID timeLineId = UUID.randomUUID(); + + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + CassandraPrimeUser user = new CassandraPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.close(); + em = emf.createEntityManager(); + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + String updateQuery = "Update CassandraPrimeUser u SET u.tweetBody=after merge where u.key= :beforeUpdate"; + Query q = em.createQuery(updateQuery); + q.setParameter("beforeUpdate", key); + q.executeUpdate(); + + em.close(); // optional,just to clear persistence cache. + + em = emf.createEntityManager(); + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + CassandraPrimeUser result = em.find(CassandraPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("after merge", result.getTweetBody()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + em.close(); + } + + /** + * delete by Named Query. + */ + private void deleteNamed() + { + UUID timeLineId = UUID.randomUUID(); + + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + + String deleteQuery = "Delete From CassandraPrimeUser u where u.key= :key"; + EntityManager em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + Query q = em.createQuery(deleteQuery); + q.setParameter("key", key); + q.executeUpdate(); + + CassandraPrimeUser result = em.find(CassandraPrimeUser.class, key); + Assert.assertNull(result); + em.close(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompoundKey.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompoundKey.java new file mode 100644 index 000000000..f2b95445d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraCompoundKey.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * @author vivek.mishra + */ +@Embeddable +public class CassandraCompoundKey +{ + @Column + private String userId; + + @Column + private int tweetId; + + @Column + private UUID timeLineId; + + @Column + private transient String fullName; + + /** + * + */ + public CassandraCompoundKey() + { + } + + /** + * @param userId + * @param tweetId + * @param timeLineId + */ + public CassandraCompoundKey(String userId, int tweetId, UUID timeLineId) + { + this.userId = userId; + this.tweetId = tweetId; + this.timeLineId = timeLineId; + this.fullName = "kuldeep"; + } + + /** + * @return the userId + */ + public String getUserId() + { + return userId; + } + + /** + * @return the tweetId + */ + public int getTweetId() + { + return tweetId; + } + + /** + * @return the timeLineId + */ + public UUID getTimeLineId() + { + return timeLineId; + } + + public String getFullName() + { + return this.fullName; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraEmbeddedAssociation.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraEmbeddedAssociation.java new file mode 100644 index 000000000..12810d06d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraEmbeddedAssociation.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.Date; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import com.impetus.client.crud.compositeType.association.UserInfo; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "CompositeUserAssociation", schema = "CompositeCassandra@composite_pu") +// @Index(index = true,columns = { "tweetBody","tweetDate" }) +public class CassandraEmbeddedAssociation +{ + + @EmbeddedId + private CassandraCompoundKey key; + + @Column + private String tweetBody; + + @Column + private Date tweetDate; + + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "userInfo_id") + private UserInfo userInfo; + + public CassandraEmbeddedAssociation() + { + } + + public CassandraEmbeddedAssociation(CassandraCompoundKey key) + { + this.key = key; + } + + /** + * @return the key + */ + public CassandraCompoundKey getKey() + { + return key; + } + + /** + * @return the tweetBody + */ + public String getTweetBody() + { + return tweetBody; + } + + /** + * @return the tweetDate + */ + public Date getTweetDate() + { + return tweetDate; + } + + /** + * @param tweetBody + * the tweetBody to set + */ + public void setTweetBody(String tweetBody) + { + this.tweetBody = tweetBody; + } + + /** + * @param tweetDate + * the tweetDate to set + */ + public void setTweetDate(Date tweetDate) + { + this.tweetDate = tweetDate; + } + + public UserInfo getUserInfo() + { + return userInfo; + } + + public void setUserInfo(UserInfo userInfo) + { + this.userInfo = userInfo; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraPrimeUser.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraPrimeUser.java new file mode 100644 index 000000000..7db9a6151 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CassandraPrimeUser.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "CompositeUser", schema = "CompositeCassandra@composite_pu") +// @Index(index = true,columns = { "tweetBody","tweetDate" }) +public class CassandraPrimeUser +{ + + @EmbeddedId + private CassandraCompoundKey key; + + @Column + private String tweetBody; + + @Column + private Date tweetDate; + + @Column + private String name; + + @Column + @Enumerated(EnumType.STRING) + private NickName nickName; + + public CassandraPrimeUser() + { + } + + public CassandraPrimeUser(CassandraCompoundKey key) + { + this.key = key; + } + + /** + * @return the key + */ + public CassandraCompoundKey getKey() + { + return key; + } + + /** + * @return the tweetBody + */ + public String getTweetBody() + { + return tweetBody; + } + + /** + * @return the tweetDate + */ + public Date getTweetDate() + { + return tweetDate; + } + + /** + * @param tweetBody + * the tweetBody to set + */ + public void setTweetBody(String tweetBody) + { + this.tweetBody = tweetBody; + } + + /** + * @param tweetDate + * the tweetDate to set + */ + public void setTweetDate(Date tweetDate) + { + this.tweetDate = tweetDate; + } + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public NickName getNickName() + { + return nickName; + } + + public void setNickName(NickName nickName) + { + this.nickName = nickName; + } + + enum NickName + { + KK, VM, AS; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompositeDataTypeTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompositeDataTypeTest.java new file mode 100644 index 000000000..124737511 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompositeDataTypeTest.java @@ -0,0 +1,513 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.client.Client; + +/** + * Junit test case for Compound/Composite key. + * + * @author vivek.mishra + * + */ +public class CompositeDataTypeTest +{ + + /** + * + */ + private static final String PERSISTENCE_UNIT = "compositedatatype"; + + private EntityManagerFactory emf; + + /** The enrolment date. */ + protected Date enrolmentDate = new Date(Long.parseLong("1344079065781")); + + /** The joining date and time. */ + protected Date joiningDateAndTime = new Date(); + + /** The date. */ + protected long date = new Date().getTime(); + + /** The new sql date. */ + protected java.sql.Date newSqlDate = new java.sql.Date(date); + + /** The enrolment time. */ + protected Date enrolmentTime = new Date(); + + /** The sql time. */ + protected java.sql.Time sqlTime = new java.sql.Time(date); + + /** The sql timestamp. */ + protected java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(date); + + /** The big decimal. */ + protected BigDecimal bigDecimal = new BigDecimal(123456789); + + /** The big integer. */ + protected BigInteger bigInteger = new BigInteger("123456789"); + + /** The number of students. */ + protected int numberOfStudents = 1000; + + /** The calendar. */ + protected Calendar calendar = Calendar.getInstance(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + loadData(); + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + } + + /** + * CRUD over Compound primary Key. + * + * @throws IllegalAccessException + * @throws InstantiationException + */ + @Test + public void onCRUD() throws InstantiationException, IllegalAccessException + { + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CompoundKeyDataType key = prepareData(new Long(12345677), 78575785897L, "Amresh", false, 10, 'A', (byte) 5, + (short) 8, (float) 69.3, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, + new Integer(3), new Long(978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, + bigInteger, calendar, CompoundKeyDataType.class.newInstance()); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + PrimeUserDataType user = new PrimeUserDataType(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + user.setIsActive(true); + em.persist(user); + + em.clear(); // optional,just to clear persistence cache. + + PrimeUserDataType result = em.find(PrimeUserDataType.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("my first tweet", result.getTweetBody()); + // Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + Assert.assertTrue(result.getIsActive()); + + em.clear();// optional,just to clear persistence cache. + + user.setTweetBody("After merge"); + em.merge(user); + + em.clear();// optional,just to clear persistence cache. + + result = em.find(PrimeUserDataType.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("After merge", result.getTweetBody()); + // Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + + // deleting composite + em.remove(result); + + em.clear();// optional,just to clear persistence cache. + + result = em.find(PrimeUserDataType.class, key); + Assert.assertNull(result); + } + + @Test + public void onQuery() throws InstantiationException, IllegalAccessException + { + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CompoundKeyDataType key = prepareData(new Long(12345677), 78575785897L, "Amresh", false, 10, 'A', (byte) 5, + (short) 8, (float) 69.3, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, + new Integer(3), new Long(978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, + bigInteger, calendar, CompoundKeyDataType.class.newInstance()); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + PrimeUserDataType user = new PrimeUserDataType(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.clear(); // optional,just to clear persistence cache. + final String noClause = "Select u from PrimeUserDataType u"; + + // secondary index support over compound key is not enabled in cassandra + // composite keys yet. DO NOT DELETE/UNCOMMENT. + + // final String withClauseOnNoncomposite = + // "Select u from PrimeUserDataType u where u.tweetDate = ?1"; + + final String withFirstCompositeColClause = "Select u from PrimeUserDataType u where u.key.studentId = :studentId"; + final String withSecondCompositeColClause = "Select u from PrimeUserDataType u where u.key.uniqueId >= :uniqueId1 and u.key.uniqueId <= :uniqueId2"; + final String withBothCompositeColClause = "Select u from PrimeUserDataType u where u.key.studentId = :studentId and u.key.uniqueId = :uniqueId"; + final String withSelectiveCompositeColClause = "Select u.key from PrimeUserDataType u where u.key = :key"; + + final String withAllCompositeColClause = "Select u from PrimeUserDataType u where u.key.studentId = :studentId and u.key.uniqueId = :uniqueId and u.key.studentName = :studentName and u.key.isExceptional = :isExceptional and u.key.age = :age and u.key.semester = :semester and u.key.digitalSignature = :digitalSignature and u.key.cgpa = :cgpa and u.key.percentage = :percentage and u.key.height = :height and u.key.enrolmentDate = :enrolmentDate and u.key.enrolmentTime = :enrolmentTime and u.key.joiningDateAndTime = :joiningDateAndTime and u.key.yearsSpent = :yearsSpent and u.key.rollNumber = :rollNumber and u.key.monthlyFee = :monthlyFee and u.key.sqlDate = :sqlDate and u.key.sqlTimestamp = :sqlTimestamp and u.key.sqlTime = :sqlTime and u.key.bigInteger = :bigInteger and u.key.calendar = :calendar"; + final String selectiveColumnTweetBodyWithAllCompositeColClause = "Select u.tweetBody from PrimeUserDataType u where u.key.studentId = :studentId and u.key.uniqueId = :uniqueId and u.key.studentName = :studentName and u.key.isExceptional = :isExceptional and u.key.age = :age and u.key.semester = :semester and u.key.digitalSignature = :digitalSignature and u.key.cgpa = :cgpa and u.key.percentage = :percentage and u.key.height = :height and u.key.enrolmentDate = :enrolmentDate and u.key.enrolmentTime = :enrolmentTime and u.key.joiningDateAndTime = :joiningDateAndTime and u.key.yearsSpent = :yearsSpent and u.key.rollNumber = :rollNumber and u.key.monthlyFee = :monthlyFee and u.key.sqlDate = :sqlDate and u.key.sqlTimestamp = :sqlTimestamp and u.key.sqlTime = :sqlTime and u.key.bigInteger = :bigInteger and u.key.calendar = :calendar"; + + // query over 1 composite and 1 non-column + + // query with no clause. + Query q = em.createQuery(noClause); + List results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withFirstCompositeColClause); + q.setParameter("studentId", new Long(12345677)); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // secondary index support over compound key is not enabled in cassandra + // composite keys yet. DO NOT DELETE/UNCOMMENT. + + // Query with composite key clause. + // q = em.createQuery(withClauseOnNoncomposite); + // q.setParameter(1, currentDate); + // results = q.getResultList(); + // Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withSecondCompositeColClause); + q.setParameter("uniqueId1", 78575785897L); + q.setParameter("uniqueId2", 78575785897L); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withBothCompositeColClause); + q.setParameter("studentId", new Long(12345677)); + q.setParameter("uniqueId", 78575785897L); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withAllCompositeColClause); + q.setParameter("studentId", new Long(12345677)); + q.setParameter("uniqueId", 78575785897L); + q.setParameter("studentName", "Amresh"); + q.setParameter("isExceptional", false); + q.setParameter("age", 10); + q.setParameter("semester", 'A'); + q.setParameter("digitalSignature", new Byte((byte) 5)); + q.setParameter("cgpa", (short) 8); + q.setParameter("percentage", (float) 69.3); + q.setParameter("height", 163.76765654); + q.setParameter("enrolmentDate", enrolmentDate); + q.setParameter("enrolmentTime", enrolmentTime); + q.setParameter("joiningDateAndTime", joiningDateAndTime); + q.setParameter("yearsSpent", new Integer(3)); + q.setParameter("rollNumber", new Long(978423946455l)); + q.setParameter("monthlyFee", 135434.89); + q.setParameter("sqlDate", newSqlDate); + q.setParameter("sqlTimestamp", sqlTimestamp); + q.setParameter("sqlTime", sqlTime); + q.setParameter("bigInteger", bigInteger); + q.setParameter("calendar", calendar); + + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + // Query with composite key with selective clause. + q = em.createQuery(withSelectiveCompositeColClause); + q.setParameter("key", key); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertNull(results.get(0).getTweetBody()); + + // // Query for selective column tweetBody with composite key clause. + q = em.createQuery(selectiveColumnTweetBodyWithAllCompositeColClause); + q.setParameter("studentId", new Long(12345677)); + q.setParameter("uniqueId", 78575785897L); + q.setParameter("studentName", "Amresh"); + q.setParameter("isExceptional", false); + q.setParameter("age", 10); + q.setParameter("semester", 'A'); + q.setParameter("digitalSignature", (byte) 5); + q.setParameter("cgpa", (short) 8); + q.setParameter("percentage", (float) 69.3); + q.setParameter("height", 163.76765654); + q.setParameter("enrolmentDate", enrolmentDate); + q.setParameter("enrolmentTime", enrolmentTime); + q.setParameter("joiningDateAndTime", joiningDateAndTime); + q.setParameter("yearsSpent", new Integer(3)); + q.setParameter("rollNumber", new Long(978423946455l)); + q.setParameter("monthlyFee", 135434.89); + q.setParameter("sqlDate", newSqlDate); + q.setParameter("sqlTimestamp", sqlTimestamp); + q.setParameter("sqlTime", sqlTime); + q.setParameter("bigInteger", bigInteger); + q.setParameter("calendar", calendar); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("my first tweet", results.get(0).getTweetBody()); + Assert.assertNull(results.get(0).getTweetDate()); + + final String selectiveColumnTweetDateWithAllCompositeColClause = "Select u.tweetDate from PrimeUserDataType u where u.key = :key"; + // Query for selective column tweetDate with composite key clause. + q = em.createQuery(selectiveColumnTweetDateWithAllCompositeColClause); + q.setParameter("key", key); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(currentDate.getTime(), results.get(0).getTweetDate().getTime()); + Assert.assertNull(results.get(0).getTweetBody()); + + final String withCompositeKeyClause = "Select u from PrimeUserDataType u where u.key = :key"; + // Query with composite key clause. + q = em.createQuery(withCompositeKeyClause); + q.setParameter("key", key); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + em.remove(user); + + em.clear();// optional,just to clear persistence cache. + } + + @Test + public void onNamedQueryTest() throws InstantiationException, IllegalAccessException + { + updateNamed(); + deleteNamed(); + + } + + /** + * Update by Named Query. + * + * @return + * @throws IllegalAccessException + * @throws InstantiationException + */ + private void updateNamed() throws InstantiationException, IllegalAccessException + { + EntityManager em = emf.createEntityManager(); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CompoundKeyDataType key = prepareData(new Long(12345677), 78575785897L, "Amresh", false, 10, 'A', (byte) 5, + (short) 8, (float) 69.3, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, + new Integer(3), new Long(978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, + bigInteger, calendar, CompoundKeyDataType.class.newInstance()); + PrimeUserDataType user = new PrimeUserDataType(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em = emf.createEntityManager(); + clients = (Map) em.getDelegate(); + client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + String updateQuery = "Update PrimeUserDataType u SET u.tweetBody=after merge where u.key= :beforeUpdate"; + Query q = em.createQuery(updateQuery); + q.setParameter("beforeUpdate", key); + q.executeUpdate(); + + PrimeUserDataType result = em.find(PrimeUserDataType.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("after merge", result.getTweetBody()); + // Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + em.close(); + } + + /** + * delete by Named Query. + * + * @throws IllegalAccessException + * @throws InstantiationException + */ + private void deleteNamed() throws InstantiationException, IllegalAccessException + { + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CompoundKeyDataType key = prepareData(new Long(12345677), 78575785897L, "Amresh", false, 10, 'A', (byte) 5, + (short) 8, (float) 69.3, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, + new Integer(3), new Long(978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, + bigInteger, calendar, CompoundKeyDataType.class.newInstance()); + + String deleteQuery = "Delete From PrimeUserDataType u where u.key= :key"; + EntityManager em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get(PERSISTENCE_UNIT); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + Query q = em.createQuery(deleteQuery); + q.setParameter("key", key); + q.executeUpdate(); + + PrimeUserDataType result = em.find(PrimeUserDataType.class, key); + Assert.assertNull(result); + em.close(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("CompositeCassandra"); + emf.close(); + } + + // DO NOT DELETE IT!! though it is automated with schema creation option. + /** + * create column family script for compound key. + */ + private void loadData() + {/* + * CassandraCli.createKeySpace("CompositeCassandra"); String cql_Query = + * "create columnfamily \"CompositeUserDataType\" (\"userId\" text, \"tweetId\" int, \"timeLineId\" uuid, \"tweetBody\" text," + * + + * " \"tweetDate\" timestamp, PRIMARY KEY(\"userId\",\"tweetId\",\"timeLineId\"))" + * ; try { CassandraCli.getClient().set_keyspace("CompositeCassandra"); } + * catch (InvalidRequestException e) { logger.error(e.getMessage()); } + * catch (TException e) { logger.error(e.getMessage()); } + * CassandraCli.executeCqlQuery(cql_Query); + */ + } + + /** + * Prepare data. + * + * @param studentId + * the student id + * @param uniqueId + * the unique id + * @param studentName + * the student name + * @param isExceptional + * the is exceptional + * @param age + * the age + * @param semester + * the semester + * @param digitalSignature + * the digital signature + * @param cgpa + * the cgpa + * @param percentage + * the percentage + * @param height + * the height + * @param enrolmentDate + * the enrolment date + * @param enrolmentTime + * the enrolment time + * @param joiningDateAndTime + * the joining date and time + * @param yearsSpent + * the years spent + * @param rollNumber + * the roll number + * @param monthlyFee + * the monthly fee + * @param newSqlDate + * the new sql date + * @param sqlTime + * the sql time + * @param sqlTimestamp + * the sql timestamp + * @param bigDecimal + * the big decimal + * @param bigInteger + * the big integer + * @param calendar + * the calendar + * @param o + * the o + * @return the person + */ + private CompoundKeyDataType prepareData(long studentId, long uniqueId, String studentName, boolean isExceptional, + int age, char semester, byte digitalSignature, short cgpa, float percentage, double height, + java.util.Date enrolmentDate, java.util.Date enrolmentTime, java.util.Date joiningDateAndTime, + Integer yearsSpent, Long rollNumber, Double monthlyFee, java.sql.Date newSqlDate, java.sql.Time sqlTime, + java.sql.Timestamp sqlTimestamp, BigDecimal bigDecimal, BigInteger bigInteger, Calendar calendar, + CompoundKeyDataType o) + { + o.setStudentId((Long) studentId); + o.setUniqueId(uniqueId); + o.setStudentName(studentName); + o.setExceptional(isExceptional); + o.setAge(age); + o.setSemester(semester); + o.setDigitalSignature(digitalSignature); + o.setCgpa(cgpa); + o.setPercentage(percentage); + o.setHeight(height); + + o.setEnrolmentDate(enrolmentDate); + o.setEnrolmentTime(enrolmentTime); + o.setJoiningDateAndTime(joiningDateAndTime); + + o.setYearsSpent(yearsSpent); + o.setRollNumber(rollNumber); + o.setMonthlyFee(monthlyFee); + o.setSqlDate(newSqlDate); + o.setSqlTime(sqlTime); + o.setSqlTimestamp(sqlTimestamp); + // o.setBigDecimal(bigDecimal); + o.setBigInteger(bigInteger); + o.setCalendar(calendar); + return o; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompoundKeyDataType.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompoundKeyDataType.java new file mode 100644 index 000000000..0c34dc9f7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/CompoundKeyDataType.java @@ -0,0 +1,481 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.math.BigInteger; +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +/** + * @author vivek.mishra + */ +@Embeddable +public class CompoundKeyDataType +{ + + // Primitive Types + // @Id + @Column(name = "STUDENT_ID") + private long studentId; + + @Column(name = "UNIQUE_ID") + private long uniqueId; + + @Column(name = "STUDENT_NAME") + private String studentName; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "AGE") + private int age; + + @Column(name = "SEMESTER") + private char semester; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "CGPA") + private short cgpa; // 1-10 + + @Column(name = "PERCENTAGE") + private float percentage; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "ROLL_NUMBER") + private Long rollNumber; + + @Column(name = "MONTHLY_FEE") + private Double monthlyFee; + + @Column(name = "SQL_DATE") + private java.sql.Date sqlDate; + + @Column(name = "SQL_TIMESTAMP") + private java.sql.Timestamp sqlTimestamp; + + @Column(name = "SQL_TIME") + private java.sql.Time sqlTime; + + @Column(name = "BIG_INT") + private BigInteger bigInteger; + + // @Column(name = "BIG_DECIMAL") + // private BigDecimal bigDecimal; + + @Column(name = "CALENDAR") + private Calendar calendar; + + /** + * + */ + public CompoundKeyDataType() + { + } + + /** + * @return the studentId + */ + public long getStudentId() + { + return studentId; + } + + /** + * @param studentId + * the studentId to set + */ + public void setStudentId(long studentId) + { + this.studentId = studentId; + } + + /** + * @return the uniqueId + */ + public long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the studentName + */ + public String getStudentName() + { + return studentName; + } + + /** + * @param studentName + * the studentName to set + */ + public void setStudentName(String studentName) + { + this.studentName = studentName; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the semester + */ + public char getSemester() + { + return semester; + } + + /** + * @param semester + * the semester to set + */ + public void setSemester(char semester) + { + this.semester = semester; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the cgpa + */ + public short getCgpa() + { + return cgpa; + } + + /** + * @param cgpa + * the cgpa to set + */ + public void setCgpa(short cgpa) + { + this.cgpa = cgpa; + } + + /** + * @return the percentage + */ + public float getPercentage() + { + return percentage; + } + + /** + * @param percentage + * the percentage to set + */ + public void setPercentage(float percentage) + { + this.percentage = percentage; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the rollNumber + */ + public Long getRollNumber() + { + return rollNumber; + } + + /** + * @param rollNumber + * the rollNumber to set + */ + public void setRollNumber(Long rollNumber) + { + this.rollNumber = rollNumber; + } + + /** + * @return the monthlyFee + */ + public Double getMonthlyFee() + { + return monthlyFee; + } + + /** + * @param monthlyFee + * the monthlyFee to set + */ + public void setMonthlyFee(Double monthlyFee) + { + this.monthlyFee = monthlyFee; + } + + public java.sql.Date getSqlDate() + { + return sqlDate; + } + + public void setSqlDate(java.sql.Date sqlDate) + { + this.sqlDate = sqlDate; + } + + /** + * @return the sqlTimestamp + */ + public java.sql.Timestamp getSqlTimestamp() + { + return sqlTimestamp; + } + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + public void setSqlTimestamp(java.sql.Timestamp sqlTimestamp) + { + this.sqlTimestamp = sqlTimestamp; + } + + /** + * @return the sqlTime + */ + public java.sql.Time getSqlTime() + { + return sqlTime; + } + + /** + * @param sqlTime + * the sqlTime to set + */ + public void setSqlTime(java.sql.Time sqlTime) + { + this.sqlTime = sqlTime; + } + + /** + * @return the bigInteger + */ + public BigInteger getBigInteger() + { + return bigInteger; + } + + /** + * @param bigInteger + * the bigInteger to set + */ + public void setBigInteger(BigInteger bigInteger) + { + this.bigInteger = bigInteger; + } + + // /** + // * @return the bigDecimal + // */ + // public BigDecimal getBigDecimal() + // { + // return bigDecimal; + // } + // + // /** + // * @param bigDecimal + // * the bigDecimal to set + // */ + // public void setBigDecimal(BigDecimal bigDecimal) + // { + // this.bigDecimal = bigDecimal; + // } + + /** + * @return the calendar + */ + public Calendar getCalendar() + { + return calendar; + } + + /** + * @param calendar + * the calendar to set + */ + public void setCalendar(Calendar calendar) + { + this.calendar = calendar; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/PrimeUserDataType.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/PrimeUserDataType.java new file mode 100644 index 000000000..bad612f7c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/PrimeUserDataType.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "CompositeUserDataType", schema = "CompositeCassandra@compositedatatype") +// @Index(index = true,columns = { "tweetBody","tweetDate" }) +public class PrimeUserDataType +{ + + @EmbeddedId + private CompoundKeyDataType key; + + @Column + private String tweetBody; + + @Column + private Date tweetDate; + + @Column + private Boolean isActive; + + public PrimeUserDataType() + { + } + + public PrimeUserDataType(CompoundKeyDataType key) + { + this.key = key; + } + + /** + * @return the key + */ + public CompoundKeyDataType getKey() + { + return key; + } + + /** + * @return the tweetBody + */ + public String getTweetBody() + { + return tweetBody; + } + + /** + * @return the tweetDate + */ + public Date getTweetDate() + { + return tweetDate; + } + + /** + * @param tweetBody + * the tweetBody to set + */ + public void setTweetBody(String tweetBody) + { + this.tweetBody = tweetBody; + } + + /** + * @param tweetDate + * the tweetDate to set + */ + public void setTweetDate(Date tweetDate) + { + this.tweetDate = tweetDate; + } + + public Boolean getIsActive() + { + return isActive; + } + + public void setIsActive(Boolean isActive) + { + this.isActive = isActive; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/AddressOTOPK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/AddressOTOPK.java new file mode 100644 index 000000000..652cf6789 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/AddressOTOPK.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "AddressOTOPK", schema = "KunderaExamples@thriftClientTest") +public class AddressOTOPK +{ + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "ADDRESS_ID") + private String addressId; + + @Column(name = "STREET") + private String street; + + @OneToOne(mappedBy = "address", fetch = FetchType.LAZY) + private UserOTOPK user; + + public String getPersonId() + { + return personId; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public String getAddressId() + { + return addressId; + } + + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + + public UserOTOPK getUser() + { + return user; + } + + public void setUser(UserOTOPK user) + { + this.user = user; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraAddressUniOTM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraAddressUniOTM.java new file mode 100644 index 000000000..723ca2a67 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraAddressUniOTM.java @@ -0,0 +1,40 @@ +package com.impetus.client.crud.compositeType.association; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraAddressUniOTM", schema = "KunderaExamples@secIdxCassandraTest") +public class CassandraAddressUniOTM +{ + + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + @Column(name = "STREET") + private String street; + + public String getAddressId() + { + return addressId; + } + + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserOTMTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserOTMTest.java new file mode 100644 index 000000000..d5afddbdd --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserOTMTest.java @@ -0,0 +1,203 @@ +/** + * + */ +package com.impetus.client.crud.compositeType.association; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * @author impadmin + * + */ +public class CassandraUserOTMTest +{ + + private static final String _KEYSPACE = "KunderaExamples"; + + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(_KEYSPACE); + loadData(); + // HashMap propertyMap = new HashMap(); + // propertyMap.put(CassandraConstants.CQL_VERSION, + // CassandraConstants.CQL_VERSION_3_0); + // propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, + // "create"); + emf = Persistence.createEntityManagerFactory("secIdxCassandraTest"); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(_KEYSPACE); + emf.close(); + } + + @Test + public void test() + { + em = emf.createEntityManager(); + + Set addresses = new HashSet(); + + CassandraAddressUniOTM address1 = new CassandraAddressUniOTM(); + address1.setAddressId("a"); + address1.setStreet("my street"); + CassandraAddressUniOTM address2 = new CassandraAddressUniOTM(); + address2.setAddressId("b"); + address2.setStreet("my new street"); + + addresses.add(address1); + addresses.add(address2); + + CassandraUserUniOTM userUniOTM = new CassandraUserUniOTM(); + userUniOTM.setPersonId("1"); + userUniOTM.setPersonName("kuldeep"); + userUniOTM.setAddresses(addresses); + + em.persist(userUniOTM); + + em.clear(); + + CassandraUserUniOTM foundObject = em.find(CassandraUserUniOTM.class, "1"); + Assert.assertNotNull(foundObject); + Assert.assertEquals(2, foundObject.getAddresses().size()); + + Query q = em.createQuery("Select u from CassandraUserUniOTM u"); + List users = q.getResultList(); + Assert.assertNotNull(users); + Assert.assertEquals(1, users.size()); + Assert.assertNotNull(users.get(0)); + Assert.assertEquals("kuldeep", users.get(0).getPersonName()); + Assert.assertEquals("1", users.get(0).getPersonId()); + Assert.assertNotNull(users.get(0).getAddresses()); + Assert.assertEquals(2, users.get(0).getAddresses().size()); + + em.remove(foundObject); + + foundObject = em.find(CassandraUserUniOTM.class, "1"); + Assert.assertNull(foundObject); + } + + /** + * Loads data. + * + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private void loadData() throws InvalidRequestException, SchemaDisagreementException, TException + { + List cfDefs = new ArrayList(); + + CfDef user = new CfDef(_KEYSPACE, "CassandraUserUniOTM"); + user.setKey_validation_class("UTF8Type"); + user.setDefault_validation_class("UTF8Type"); + user.setComparator_type("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user.addToColumn_metadata(columnDef); + + CfDef address = new CfDef(_KEYSPACE, "CassandraAddressUniOTM"); + address.setKey_validation_class("UTF8Type"); + address.setDefault_validation_class("UTF8Type"); + address.setComparator_type("UTF8Type"); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("PERSON_ID".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("STREET".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + + address.addToColumn_metadata(columnDef1); + address.addToColumn_metadata(columnDef2); + + cfDefs.add(user); + cfDefs.add(address); + KsDef ksDef = null; + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(_KEYSPACE); + CassandraCli.client.set_keyspace(_KEYSPACE); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + if (cfDef1.getName().equals("CassandraUserUniOTM")) + { + CassandraCli.client.system_drop_column_family("CassandraUserUniOTM"); + } + if (cfDef1.getName().equals("CassandraAddressUniOTM")) + { + CassandraCli.client.system_drop_column_family("CassandraAddressUniOTM"); + } + } + CassandraCli.client.system_add_column_family(user); + CassandraCli.client.system_add_column_family(address); + } + catch (NotFoundException e) + { + + ksDef = new org.apache.cassandra.thrift.KsDef(_KEYSPACE, "org.apache.cassandra.locator.SimpleStrategy", + cfDefs); + + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + + CassandraCli.client.set_keyspace(_KEYSPACE); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserUniOTM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserUniOTM.java new file mode 100644 index 000000000..f2f4f9142 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/CassandraUserUniOTM.java @@ -0,0 +1,60 @@ +package com.impetus.client.crud.compositeType.association; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraUserUniOTM", schema = "KunderaExamples@secIdxCassandraTest") +public class CassandraUserUniOTM +{ + + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "PERSON_NAME") + private String personName; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "PERSON_ID") + private Set addresses; + + public String getPersonId() + { + return personId; + } + + public String getPersonName() + { + return personName; + } + + public void setPersonName(String personName) + { + this.personName = personName; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public Set getAddresses() + { + return addresses; + } + + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java new file mode 100644 index 000000000..595744dab --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "UserInfo", schema = "CompositeCassandra@composite_pu") +public class UserInfo +{ + + @Id + @Column(name = "userInfo_id") + private String userInfoId; + + @Column(name = "first_name") + private String firstName; + + @Column(name = "last_name") + private String lastName; + + @Column(name = "age") + private int age; + + /** + * + */ + public UserInfo() + { + } + + /** + * @param userInfoId + * @param firstName + * @param lastName + * @param age + * @param timeLine + */ + public UserInfo(String userInfoId, String firstName, String lastName, int age/* + * , + * CassandraPrimeUser + * timeLine + */) + { + super(); + this.userInfoId = userInfoId; + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + // this.timeLine = timeLine; + } + + /** + * @return the userInfoId + */ + public String getUserInfoId() + { + return userInfoId; + } + + /** + * @return the firstName + */ + public String getFirstName() + { + return firstName; + } + + /** + * @return the lastName + */ + public String getLastName() + { + return lastName; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + // /** + // * @return the timeLine + // */ + // public CassandraPrimeUser getTimeLine() + // { + // return timeLine; + // } + + /** + * @param firstName + * the firstName to set + */ + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java new file mode 100644 index 000000000..6387a94ff --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java @@ -0,0 +1,216 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.CassandraClientBase; +import com.impetus.client.crud.compositeType.CassandraCompoundKey; +import com.impetus.client.crud.compositeType.CassandraEmbeddedAssociation; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.client.Client; + +/** + * @author vivek.mishra + * + */ +public class UserInfoTest +{ + private EntityManagerFactory emf; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + loadData(); + Map props = new HashMap(1); + props.put("kundera.ddl.auto.prepare", ""); + emf = Persistence.createEntityManagerFactory("composite_pu", props); + } + + @Test + public void onCRUD() + { + EntityManager em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get("composite_pu"); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + // Persist + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + CassandraEmbeddedAssociation timeLine = new CassandraEmbeddedAssociation(key); + timeLine.setTweetBody("my first tweet"); + timeLine.setTweetDate(currentDate); + + UserInfo userInfo = new UserInfo("mevivs_info", "Vivek", "Mishra", 31); + timeLine.setUserInfo(userInfo); + em.persist(timeLine); + em.clear(); + + // Find + CassandraEmbeddedAssociation result = em.find(CassandraEmbeddedAssociation.class, key); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate, result.getTweetDate()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals("Vivek", result.getUserInfo().getFirstName()); + Assert.assertEquals(31, result.getUserInfo().getAge()); + + result.getUserInfo().setFirstName("Kuldeep"); + result.getUserInfo().setAge(23); + + em.merge(result); + + em.clear(); + + // Find + result = null; + result = em.find(CassandraEmbeddedAssociation.class, key); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate, result.getTweetDate()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals("Kuldeep", result.getUserInfo().getFirstName()); + Assert.assertEquals(23, result.getUserInfo().getAge()); + + em.remove(result); + + em.clear(); + result = em.find(CassandraEmbeddedAssociation.class, key); + Assert.assertNull(result); + + } + + @Test + public void onQuery() + { + EntityManager em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + Client client = clients.get("composite_pu"); + ((CassandraClientBase) client).setCqlVersion("3.0.0"); + + // Persist + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + CassandraCompoundKey key = new CassandraCompoundKey("mevivs", 1, timeLineId); + CassandraEmbeddedAssociation timeLine = new CassandraEmbeddedAssociation(key); + timeLine.setTweetBody("my first tweet"); + timeLine.setTweetDate(currentDate); + + UserInfo userInfo = new UserInfo("mevivs_info", "Vivek", "Mishra", 31); + timeLine.setUserInfo(userInfo); + em.persist(timeLine); + + em.clear(); // optional,just to clear persistence cache. + + final String noClause = "Select t from CassandraEmbeddedAssociation t"; + + Query query = em.createQuery(noClause); + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("Vivek", results.get(0).getUserInfo().getFirstName()); + Assert.assertEquals(31, results.get(0).getUserInfo().getAge()); + + em.remove(timeLine); + + em.clear();// optional,just to clear persistence cache. + + UserInfo user_Info = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNull(user_Info); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("CompositeCassandra"); + emf.close(); + } + + /** + * Loads data. + * + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private void loadData() throws InvalidRequestException, SchemaDisagreementException, TException + { + List cfDefs = new ArrayList(); + CfDef cfDef = new CfDef("CompositeCassandra", "UserInfo"); + cfDef.setKey_validation_class("UTF8Type"); + cfDef.setDefault_validation_class("UTF8Type"); + cfDef.setComparator_type("UTF8Type"); + cfDef.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("first_name".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("last_name".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef1); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("age".getBytes()), "Int32Type"); + columnDef2.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef2); + cfDefs.add(cfDef); + KsDef ksDef = new KsDef("CompositeCassandra", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.getClient().system_add_keyspace(ksDef); + + CassandraCli.executeCqlQuery("USE \"CompositeCassandra\""); + + CassandraCli + .executeCqlQuery("CREATE TABLE \"CompositeUserAssociation\" (\"userId\" varchar,\"tweetId\" int,\"timeLineId\" uuid, \"tweetBody\" varchar, \"tweetDate\" timestamp, \"userInfo_id\" varchar,\"first_name\" varchar,\"last_name\" varchar, \"age\" int, PRIMARY KEY (\"userId\", \"tweetId\",\"timeLineId\"))"); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPK.java new file mode 100644 index 000000000..1a8b0469c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPK.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +@Entity +@Table(name = "UserOTOPK", schema = "KunderaExamples@thriftClientTest") +public class UserOTOPK +{ + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "PERSON_NAME") + private String personName; + + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, optional = false) + @PrimaryKeyJoinColumn + private AddressOTOPK address; + + public String getPersonId() + { + return personId; + } + + public String getPersonName() + { + return personName; + } + + public void setPersonName(String personName) + { + this.personName = personName; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public AddressOTOPK getAddress() + { + return address; + } + + public void setAddress(AddressOTOPK address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPKTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPKTest.java new file mode 100644 index 000000000..8084bbcc1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/compositeType/association/UserOTOPKTest.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +/** + * @author impadmin + * + */ +public class UserOTOPKTest +{ + private String keyspace = "KunderaExamples"; + + private EntityManagerFactory emf; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.initClient(); + loadData(); + emf = Persistence.createEntityManagerFactory("thriftClientTest"); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(keyspace); + emf.close(); + } + + @Test + public void testOTOPk() + { + EntityManager em = emf.createEntityManager(); + + AddressOTOPK addressOTOPK = new AddressOTOPK(); + addressOTOPK.setAddressId("xyz"); + addressOTOPK.setStreet("STTRRREEEETTTTT"); + + UserOTOPK userOTOPK = new UserOTOPK(); + userOTOPK.setPersonId("1234"); + userOTOPK.setPersonName("Kuldeep"); + userOTOPK.setAddress(addressOTOPK); + + em.persist(userOTOPK); + + em.clear(); + + UserOTOPK otopk = em.find(UserOTOPK.class, "1234"); + Assert.assertNotNull(otopk); + Assert.assertNotNull(otopk.getAddress()); + Assert.assertEquals("Kuldeep", otopk.getPersonName()); + Assert.assertEquals("1234", otopk.getAddress().getPersonId()); + Assert.assertEquals("xyz", otopk.getAddress().getAddressId()); + Assert.assertEquals("STTRRREEEETTTTT", otopk.getAddress().getStreet()); + + em.clear(); + + Query q = em.createQuery("Select u from UserOTOPK u"); + List users = q.getResultList(); + Assert.assertNotNull(users); + Assert.assertEquals(1, users.size()); + Assert.assertNotNull(users.get(0)); + Assert.assertNotNull(users.get(0).getAddress()); + Assert.assertEquals("STTRRREEEETTTTT", users.get(0).getAddress().getStreet()); + em.close(); + + } + + /** + * Loads data. + * + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * @throws TException + */ + private void loadData() throws InvalidRequestException, SchemaDisagreementException, TException + { + List cfDefs = new ArrayList(); + + CfDef user = new CfDef(keyspace, "UserOTOPK"); + user.setKey_validation_class("UTF8Type"); + user.setDefault_validation_class("UTF8Type"); + user.setComparator_type("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("PERSON_NAME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + user.addToColumn_metadata(columnDef); + + CfDef address = new CfDef(keyspace, "AddressOTOPK"); + address.setKey_validation_class("UTF8Type"); + address.setDefault_validation_class("UTF8Type"); + address.setComparator_type("UTF8Type"); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("ADDRESS_ID".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("STREET".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + + address.addToColumn_metadata(columnDef1); + address.addToColumn_metadata(columnDef2); + + cfDefs.add(user); + cfDefs.add(address); + KsDef ksDef = null; + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + if (cfDef1.getName().equalsIgnoreCase("UserOTOPK")) + { + CassandraCli.client.system_drop_column_family("UserOTOPK"); + } + if (cfDef1.getName().equalsIgnoreCase("AddressOTOPK")) + { + CassandraCli.client.system_drop_column_family("AddressOTOPK"); + } + } + CassandraCli.client.system_add_column_family(user); + CassandraCli.client.system_add_column_family(address); + } + catch (NotFoundException e) + { + + ksDef = new org.apache.cassandra.thrift.KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", + cfDefs); + + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/Counters.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/Counters.java new file mode 100644 index 000000000..9df5a68ef --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/Counters.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.countercolumns; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "counters", schema = "KunderaCounterColumn@CassandraCounterTest") +public class Counters +{ + @Id + private String id; + + @Column + private int counter; + + @Column + private transient int count; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the counter1 + */ + public int getCounter() + { + return counter; + } + + /** + * @param counter1 + * the counter1 to set + */ + public void setCounter(int counter) + { + this.counter = counter; + } + + public int getCount() + { + return count; + } + + public void setCount(int count) + { + this.count = count; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/CountersTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/CountersTest.java new file mode 100644 index 000000000..81a809ad3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/CountersTest.java @@ -0,0 +1,426 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.countercolumns; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Cassandra.Client; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; + +/** + * Counter column test case for Counter column family in cassandra. + * + * @author kuldeep.mishra + * + */ +public class CountersTest +{ + private static final String id1 = "12"; + + private static final String id2 = "15"; + + private static final String id3 = "18"; + + private EntityManagerFactory emf; + + private static final boolean RUN_IN_EMBEDDED_MODE = true; + + private static final boolean AUTO_MANAGE_SCHEMA = true; + + private String keyspace = "KunderaCounterColumn"; + + protected Map propertyMap = new HashMap(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + // createSchema(); + } + if (propertyMap.isEmpty()) + { + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + emf = Persistence.createEntityManagerFactory("CassandraCounterTest", propertyMap); + } + + private void createSchema() throws InvalidRequestException, TException, SchemaDisagreementException + { + Client client = CassandraCli.getClient(); + CassandraCli.createKeySpace(keyspace); + client.set_keyspace(keyspace); + + CfDef cfDef = new CfDef(); + cfDef.keyspace = keyspace; + cfDef.name = "counters"; + cfDef.default_validation_class = "CounterColumnType"; + cfDef.key_validation_class = "UTF8Type"; + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("counter".getBytes()), "CounterColumnType"); + columnDef.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef); + cfDef.comparator_type = "UTF8Type"; + + client.system_add_column_family(cfDef); + } + + private void startServer() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + CassandraCli.cassandraSetUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + if (/* AUTO_MANAGE_SCHEMA && CassandraCli.keyspaceExist(keyspace) */CassandraCli.client != null) + { + CassandraCli.dropKeySpace(keyspace); + } + } + + @Test + public void testCRUDOnCounter() + { + incrCounter(); + decrCounter(); + findCounter(); + selectAllQuery(); + queryGTEQOnId(); + queryLTEQOnId(); + rangeQuery(); + mergeCounter(); + updateNamedQueryOnCounter(); + deleteNamedQueryOnCounter(); + deleteCounter(); + CassandraCli.truncateColumnFamily(keyspace, "counters"); + } + + public void incrCounter() + { + EntityManager em = emf.createEntityManager(); + Counters counter = new Counters(); + counter.setCounter(12); + counter.setId(id1); + em.persist(counter); + + Counters counter1 = new Counters(); + counter1.setCounter(15); + counter1.setId(id2); + em.persist(counter1); + + Counters counter2 = new Counters(); + counter2.setCounter(18); + counter2.setId(id3); + em.persist(counter2); + + em.close(); + } + + private void decrCounter() + { + EntityManager em = emf.createEntityManager(); + Counters counter1 = new Counters(); + counter1.setCounter(-10); + counter1.setId(id1); + em.persist(counter1); + + Counters counter2 = new Counters(); + counter2.setCounter(-10); + counter2.setId(id2); + em.persist(counter2); + + Counters counter3 = new Counters(); + counter3.setCounter(-10); + counter3.setId(id3); + em.persist(counter3); + + em.close(); + } + + public void findCounter() + { + EntityManager em = emf.createEntityManager(); + Counters counter1 = new Counters(); + counter1 = em.find(Counters.class, id1); + Assert.assertNotNull(counter1); + Assert.assertNotNull(counter1.getCounter()); + Assert.assertEquals(2, counter1.getCounter()); + + Counters counter2 = new Counters(); + counter2 = em.find(Counters.class, id2); + Assert.assertNotNull(counter2); + Assert.assertNotNull(counter2.getCounter()); + Assert.assertEquals(5, counter2.getCounter()); + + Counters counter3 = new Counters(); + counter3 = em.find(Counters.class, id3); + Assert.assertNotNull(counter3); + Assert.assertNotNull(counter3.getCounter()); + Assert.assertEquals(8, counter3.getCounter()); + + em.close(); + } + + public void deleteCounter() + { + EntityManager em = emf.createEntityManager(); + Counters counters = new Counters(); + counters = em.find(Counters.class, id3); + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + em.remove(counters); + + EntityManager em1 = emf.createEntityManager(); + counters = em1.find(Counters.class, id3); + Assert.assertNull(counters); + + em.close(); + } + + public void mergeCounter() + { + EntityManager em = emf.createEntityManager(); + Counters counters = new Counters(); + counters = em.find(Counters.class, id1); + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + try + { + em.merge(counters); + } + catch (KunderaException ke) + { + Assert.assertEquals("java.lang.UnsupportedOperationException: Merge is not permitted on counter column! ", + ke.getMessage()); + } + finally + { + em.close(); + } + } + + public void selectAllQuery() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from Counters c"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(3, r.size()); + int counter = 0; + for (Counters counters : r) + { + if (counters.getId().equals(id1)) + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(2, counters.getCounter()); + } + else if (counters.getId().equals(id2)) + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(5, counters.getCounter()); + } + else + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(id3, counters.getId()); + Assert.assertEquals(8, counters.getCounter()); + } + + } + Assert.assertEquals(3, counter); + em.close(); + } + + /** + * + */ + private void rangeQuery() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from Counters c where c.id between 12 and 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int counter = 0; + for (Counters counters : r) + { + if (counters.getId().equals(id1)) + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(2, counters.getCounter()); + } + else + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(id2, counters.getId()); + Assert.assertEquals(5, counters.getCounter()); + } + } + Assert.assertEquals(2, counter); + em.close(); + } + + private void queryGTEQOnId() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from Counters c where c.id >= 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int counter = 0; + for (Counters counters : r) + { + if (counters.getId().equals(id2)) + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(5, counters.getCounter()); + } + else + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(id3, counters.getId()); + Assert.assertEquals(8, counters.getCounter()); + } + + } + Assert.assertEquals(2, counter); + em.close(); + } + + private void queryLTEQOnId() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from Counters c where c.id <= 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int counter = 0; + for (Counters counters : r) + { + if (counters.getId().equals(id1)) + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(2, counters.getCounter()); + } + else + { + counter++; + Assert.assertNotNull(counters); + Assert.assertNotNull(counters.getCounter()); + Assert.assertEquals(id2, counters.getId()); + Assert.assertEquals(5, counters.getCounter()); + } + + } + Assert.assertEquals(2, counter); + em.close(); + } + + private void updateNamedQueryOnCounter() + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update Counters c SET c.counter=23 where c.id=12"; + Query q = em.createQuery(updateQuery); + + try + { + q.executeUpdate(); + } + catch (UnsupportedOperationException uoe) + { + Assert.assertEquals("Invalid operation! Merge is not possible over counter column.", uoe.getMessage()); + } + finally + { + em.close(); + } + } + + private void deleteNamedQueryOnCounter() + { + EntityManager em = emf.createEntityManager(); + String deleteQuery = "Delete From Counters c where c.id <= " + id2; + + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + + Counters counter2 = new Counters(); + counter2 = em.find(Counters.class, id1); + Assert.assertNull(counter2); + + Counters counter3 = new Counters(); + counter3 = em.find(Counters.class, id2); + Assert.assertNull(counter3); + + em.close(); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SubCounter.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SubCounter.java new file mode 100644 index 000000000..2d0bc8f53 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SubCounter.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.countercolumns; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class SubCounter +{ + + @Column(name = "SUB_COUNTER") + private long subCounter; + + /** + * @return the subCounter + */ + public long getSubCounter() + { + return subCounter; + } + + /** + * @param subCounter + * the subCounter to set + */ + public void setSubCounter(long subCounter) + { + this.subCounter = subCounter; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCounters.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCounters.java new file mode 100644 index 000000000..c3f55a303 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCounters.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.countercolumns; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "SuperCounters", schema = "KunderaCounterColumn@CassandraCounterTest") +public class SuperCounters +{ + @Id + @Column(name = "ID") + private String id; + + @Column(name = "COUNTER") + private int counter; + + @Column(name = "Long_COUNTER") + private long lCounter; + + @Embedded + private SubCounter subCounter; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the counter + */ + public int getCounter() + { + return counter; + } + + /** + * @param counter + * the counter to set + */ + public void setCounter(int counter) + { + this.counter = counter; + } + + /** + * @return the subCounter + */ + public SubCounter getSubCounter() + { + return subCounter; + } + + /** + * @param subCounter + * the subCounter to set + */ + public void setSubCounter(SubCounter subCounter) + { + this.subCounter = subCounter; + } + + /** + * @return the lCounter + */ + public long getlCounter() + { + return lCounter; + } + + /** + * @param lCounter + * the lCounter to set + */ + public void setlCounter(long lCounter) + { + this.lCounter = lCounter; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCountersTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCountersTest.java new file mode 100644 index 000000000..fe5bf1627 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/countercolumns/SuperCountersTest.java @@ -0,0 +1,480 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.countercolumns; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.apache.cassandra.thrift.Cassandra.Client; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; + +/** + * @author impadmin + * + */ +public class SuperCountersTest +{ + private static final String id1 = "12"; + + private static final String id2 = "15"; + + private static final String id3 = "18"; + + private EntityManagerFactory emf; + + private static final boolean RUN_IN_EMBEDDED_MODE = true; + + private static final boolean AUTO_MANAGE_SCHEMA = true; + + private String keyspace = "KunderaCounterColumn"; + + protected Map propertyMap = new HashMap(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + if (propertyMap.isEmpty()) + { + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + emf = Persistence.createEntityManagerFactory("CassandraCounterTest"); + } + + private void createSchema() throws InvalidRequestException, TException, SchemaDisagreementException + { + Client client = CassandraCli.getClient(); + CassandraCli.createKeySpace(keyspace); + client.set_keyspace(keyspace); + + CfDef cfDef = new CfDef(); + cfDef.keyspace = keyspace; + cfDef.name = "SuperCounters"; + cfDef.column_type = "Super"; + cfDef.default_validation_class = "CounterColumnType"; + cfDef.comparator_type = "UTF8Type"; + client.system_add_column_family(cfDef); + } + + private void startServer() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + CassandraCli.cassandraSetUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + emf.close(); + if (/* AUTO_MANAGE_SCHEMA && CassandraCli.keyspaceExist(keyspace) */CassandraCli.client != null) + { + CassandraCli.dropKeySpace(keyspace); + } + } + + @Test + public void testCRUDOnSuperCounter() + { + incrSuperCounter(); + findSuperCounter(); + decrSuperCounter(); + selectAllQuery(); + queryGTEQOnId(); + queryLTEQOnId(); + rangeQuery(); + mergeCounter(); + updateNamedQueryOnCounter(); + deleteNamedQueryOnCounter(); + deleteSuperCounter(); + } + + private void deleteNamedQueryOnCounter() + { + EntityManager em = emf.createEntityManager(); + String deleteQuery = "Delete From SuperCounters c where c.id <= " + id2; + + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + + em.clear(); + SuperCounters counter2 = new SuperCounters(); + counter2 = em.find(SuperCounters.class, id1); + Assert.assertNull(counter2); + + SuperCounters counter3 = new SuperCounters(); + counter3 = em.find(SuperCounters.class, id2); + Assert.assertNull(counter3); + + em.close(); + + } + + private void updateNamedQueryOnCounter() + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update SuperCounters c SET c.counter=23 where c.id=12"; + Query q = em.createQuery(updateQuery); + + try + { + q.executeUpdate(); + } + catch (UnsupportedOperationException uoe) + { + Assert.assertEquals("Invalid operation! Merge is not possible over counter column.", uoe.getMessage()); + } + finally + { + em.close(); + } + + } + + private void mergeCounter() + { + EntityManager em = emf.createEntityManager(); + SuperCounters counter = new SuperCounters(); + counter = em.find(SuperCounters.class, id1); + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + try + { + em.merge(counter); + } + catch (KunderaException ke) + { + Assert.assertEquals("java.lang.UnsupportedOperationException: Merge is not permitted on counter column! ", + ke.getMessage()); + } + finally + { + em.close(); + } + + } + + private void rangeQuery() + { + + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from SuperCounters c where c.id between 12 and 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int count = 0; + for (SuperCounters counter : r) + { + if (id1.equalsIgnoreCase(counter.getId())) + { + count++; + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(2, counter.getCounter()); + Assert.assertEquals(2223, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + else + { + count++; + Assert.assertNotNull(counter); + Assert.assertEquals(id2, counter.getId()); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(5, counter.getCounter()); + Assert.assertEquals(2224, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + } + Assert.assertEquals(2, count); + } + + private void queryLTEQOnId() + { + + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from SuperCounters c where c.id <= 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int count = 0; + for (SuperCounters counter : r) + { + if (id1.equalsIgnoreCase(counter.getId())) + { + count++; + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(2, counter.getCounter()); + Assert.assertEquals(2223, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + else + { + count++; + Assert.assertNotNull(counter); + Assert.assertEquals(id2, counter.getId()); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(5, counter.getCounter()); + Assert.assertEquals(2224, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + } + Assert.assertEquals(2, count); + } + + private void queryGTEQOnId() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from SuperCounters c where c.id >= 15"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(2, r.size()); + int count = 0; + for (SuperCounters counter : r) + { + if (id2.equalsIgnoreCase(counter.getId())) + { + count++; + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(5, counter.getCounter()); + Assert.assertEquals(2224, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + else + { + count++; + Assert.assertNotNull(counter); + Assert.assertEquals(id3, counter.getId()); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(8, counter.getCounter()); + Assert.assertEquals(2225, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + } + Assert.assertEquals(2, count); + } + + private void deleteSuperCounter() + { + EntityManager em = emf.createEntityManager(); + SuperCounters counter = new SuperCounters(); + counter = em.find(SuperCounters.class, id3); + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(8, counter.getCounter()); + Assert.assertEquals(2225, counter.getlCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + em.remove(counter); + + EntityManager em1 = emf.createEntityManager(); + counter = em1.find(SuperCounters.class, id3); + Assert.assertNull(counter); + + em.close(); + + } + + private void findSuperCounter() + { + + EntityManager em = emf.createEntityManager(); + SuperCounters superCounter = new SuperCounters(); + superCounter = em.find(SuperCounters.class, id1); + Assert.assertNotNull(superCounter); + Assert.assertNotNull(superCounter.getCounter()); + Assert.assertNotNull(superCounter.getSubCounter()); + Assert.assertEquals(12, superCounter.getCounter()); + Assert.assertEquals(12223, superCounter.getlCounter()); + Assert.assertEquals(23, superCounter.getSubCounter().getSubCounter()); + + SuperCounters superCounter1 = new SuperCounters(); + superCounter1 = em.find(SuperCounters.class, id2); + Assert.assertNotNull(superCounter1); + Assert.assertNotNull(superCounter1.getCounter()); + Assert.assertNotNull(superCounter1.getSubCounter()); + Assert.assertEquals(15, superCounter1.getCounter()); + Assert.assertEquals(12224, superCounter1.getlCounter()); + Assert.assertEquals(23, superCounter1.getSubCounter().getSubCounter()); + + SuperCounters superCounter2 = new SuperCounters(); + superCounter2 = em.find(SuperCounters.class, id3); + Assert.assertNotNull(superCounter2); + Assert.assertNotNull(superCounter2.getCounter()); + Assert.assertNotNull(superCounter2.getSubCounter()); + Assert.assertEquals(18, superCounter2.getCounter()); + Assert.assertEquals(12225, superCounter2.getlCounter()); + Assert.assertEquals(23, superCounter2.getSubCounter().getSubCounter()); + + em.close(); + } + + private void incrSuperCounter() + { + + EntityManager em = emf.createEntityManager(); + SuperCounters superCounter = new SuperCounters(); + superCounter.setCounter(12); + superCounter.setId(id1); + superCounter.setlCounter(12223); + SubCounter subCounter = new SubCounter(); + subCounter.setSubCounter(23); + superCounter.setSubCounter(subCounter); + em.persist(superCounter); + + SuperCounters superCounter1 = new SuperCounters(); + superCounter1.setCounter(15); + superCounter1.setId(id2); + superCounter1.setlCounter(12224); + SubCounter subCounter1 = new SubCounter(); + subCounter1.setSubCounter(23); + superCounter1.setSubCounter(subCounter1); + em.persist(superCounter1); + + SuperCounters superCounter2 = new SuperCounters(); + superCounter2.setCounter(18); + superCounter2.setId(id3); + superCounter2.setlCounter(12225); + SubCounter subCounter2 = new SubCounter(); + subCounter2.setSubCounter(23); + superCounter2.setSubCounter(subCounter2); + em.persist(superCounter2); + + em.close(); + + } + + private void decrSuperCounter() + { + EntityManager em = emf.createEntityManager(); + SuperCounters superCounter = new SuperCounters(); + superCounter.setCounter(-10); + superCounter.setId(id1); + superCounter.setlCounter(-10000); + SubCounter subCounter = new SubCounter(); + subCounter.setSubCounter(-20); + superCounter.setSubCounter(subCounter); + em.persist(superCounter); + + SuperCounters superCounter1 = new SuperCounters(); + superCounter1.setCounter(-10); + superCounter1.setId(id2); + superCounter1.setlCounter(-10000); + SubCounter subCounter1 = new SubCounter(); + subCounter1.setSubCounter(-20); + superCounter1.setSubCounter(subCounter1); + em.persist(superCounter1); + + SuperCounters superCounter2 = new SuperCounters(); + superCounter2.setCounter(-10); + superCounter2.setId(id3); + superCounter2.setlCounter(-10000); + SubCounter subCounter2 = new SubCounter(); + subCounter2.setSubCounter(-20); + superCounter2.setSubCounter(subCounter2); + em.persist(superCounter2); + + em.close(); + + } + + public void selectAllQuery() + { + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery("select c from SuperCounters c"); + List r = q.getResultList(); + Assert.assertNotNull(r); + Assert.assertEquals(3, r.size()); + int count = 0; + for (SuperCounters counter : r) + { + if (id1.equalsIgnoreCase(counter.getId())) + { + count++; + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(2, counter.getCounter()); + Assert.assertEquals(2223, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + else if (id2.equalsIgnoreCase(counter.getId())) + { + count++; + Assert.assertNotNull(counter); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(5, counter.getCounter()); + Assert.assertEquals(2224, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + else + { + count++; + Assert.assertNotNull(counter); + Assert.assertEquals(id3, counter.getId()); + Assert.assertNotNull(counter.getCounter()); + Assert.assertEquals(8, counter.getCounter()); + Assert.assertEquals(2225, counter.getlCounter()); + Assert.assertNotNull(counter.getSubCounter()); + Assert.assertEquals(3, counter.getSubCounter().getSubCounter()); + } + } + Assert.assertEquals(3, count); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/CassandraBase.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/CassandraBase.java new file mode 100644 index 000000000..c275e8800 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/CassandraBase.java @@ -0,0 +1,91 @@ +package com.impetus.client.crud.datatypes; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.datatypes.datagenerator.DataGenerator; +import com.impetus.kundera.datatypes.datagenerator.DataGeneratorFactory; + +public abstract class CassandraBase +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + protected EntityManagerFactory emf; + + protected Map propertyMap; + + protected void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + } + emf = Persistence.createEntityManagerFactory("CassandraDataTypeTest", propertyMap); + } + + protected void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + DataGenerator dataGenerator; + + DataGeneratorFactory factory = new DataGeneratorFactory(); + + protected Object getMaxValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.maxValue(); + } + + protected Object getMinValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.minValue(); + } + + protected Object getRandomValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.randomValue(); + } + + protected Object getPartialValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.partialValue(); + } + + protected abstract void startCluster(); + + protected abstract void stopCluster(); + + protected abstract void createSchema(); + + protected abstract void dropSchema(); +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandra.java new file mode 100644 index 000000000..656344da8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandra.java @@ -0,0 +1,484 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "STUDENT", schema = "KunderaExamples@secIdxCassandraTest") +@IndexCollection(columns = { @Index(name = "uniqueId"), @Index(name = "studentName"), @Index(name = "isExceptional"), + @Index(name = "age"), @Index(name = "semester"), @Index(name = "digitalSignature"), @Index(name = "cgpa"), + @Index(name = "percentage"), @Index(name = "height"), @Index(name = "enrolmentDate"), + @Index(name = "enrolmentTime"), @Index(name = "joiningDateAndTime"), @Index(name = "yearsSpent"), + @Index(name = "rollNumber"), @Index(name = "monthlyFee"), @Index(name = "sqlDate"), + @Index(name = "sqlTimestamp"), @Index(name = "sqlTime"), @Index(name = "bigInteger"), + @Index(name = "bigDecimal"), @Index(name = "calendar") }) +public class StudentCassandra implements StudentEntityDef +{ + // Primitive Types + @Id + @Column(name = "STUDENT_ID") + private long studentId; + + @Column(name = "UNIQUE_ID") + private long uniqueId; + + @Column(name = "STUDENT_NAME") + private String studentName; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "AGE") + private int age; + + @Column(name = "SEMESTER") + private char semester; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "CGPA") + private short cgpa; // 1-10 + + @Column(name = "PERCENTAGE") + private float percentage; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "ROLL_NUMBER") + private Long rollNumber; + + @Column(name = "MONTHLY_FEE") + private Double monthlyFee; + + @Column(name = "SQL_DATE") + private java.sql.Date sqlDate; + + @Column(name = "SQL_TIMESTAMP") + private java.sql.Timestamp sqlTimestamp; + + @Column(name = "SQL_TIME") + private java.sql.Time sqlTime; + + @Column(name = "BIG_INT") + private BigInteger bigInteger; + + @Column(name = "BIG_DECIMAL") + private BigDecimal bigDecimal; + + @Column(name = "CALENDAR") + private Calendar calendar; + + /** + * @return the studentId + */ + public long getStudentId() + { + return studentId; + } + + /** + * @param studentId + * the studentId to set + */ + public void setStudentId(long studentId) + { + this.studentId = studentId; + } + + /** + * @return the uniqueId + */ + public long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the studentName + */ + public String getStudentName() + { + return studentName; + } + + /** + * @param studentName + * the studentName to set + */ + public void setStudentName(String studentName) + { + this.studentName = studentName; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the semester + */ + public char getSemester() + { + return semester; + } + + /** + * @param semester + * the semester to set + */ + public void setSemester(char semester) + { + this.semester = semester; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the cgpa + */ + public short getCgpa() + { + return cgpa; + } + + /** + * @param cgpa + * the cgpa to set + */ + public void setCgpa(short cgpa) + { + this.cgpa = cgpa; + } + + /** + * @return the percentage + */ + public float getPercentage() + { + return percentage; + } + + /** + * @param percentage + * the percentage to set + */ + public void setPercentage(float percentage) + { + this.percentage = percentage; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the rollNumber + */ + public Long getRollNumber() + { + return rollNumber; + } + + /** + * @param rollNumber + * the rollNumber to set + */ + public void setRollNumber(Long rollNumber) + { + this.rollNumber = rollNumber; + } + + /** + * @return the monthlyFee + */ + public Double getMonthlyFee() + { + return monthlyFee; + } + + /** + * @param monthlyFee + * the monthlyFee to set + */ + public void setMonthlyFee(Double monthlyFee) + { + this.monthlyFee = monthlyFee; + } + + public java.sql.Date getSqlDate() + { + return sqlDate; + } + + public void setSqlDate(java.sql.Date sqlDate) + { + this.sqlDate = sqlDate; + } + + /** + * @return the sqlTimestamp + */ + public java.sql.Timestamp getSqlTimestamp() + { + return sqlTimestamp; + } + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + public void setSqlTimestamp(java.sql.Timestamp sqlTimestamp) + { + this.sqlTimestamp = sqlTimestamp; + } + + /** + * @return the sqlTime + */ + public java.sql.Time getSqlTime() + { + return sqlTime; + } + + /** + * @param sqlTime + * the sqlTime to set + */ + public void setSqlTime(java.sql.Time sqlTime) + { + this.sqlTime = sqlTime; + } + + /** + * @return the bigInteger + */ + public BigInteger getBigInteger() + { + return bigInteger; + } + + /** + * @param bigInteger + * the bigInteger to set + */ + public void setBigInteger(BigInteger bigInteger) + { + this.bigInteger = bigInteger; + } + + /** + * @return the bigDecimal + */ + public BigDecimal getBigDecimal() + { + return bigDecimal; + } + + /** + * @param bigDecimal + * the bigDecimal to set + */ + public void setBigDecimal(BigDecimal bigDecimal) + { + this.bigDecimal = bigDecimal; + } + + /** + * @return the calendar + */ + public Calendar getCalendar() + { + return calendar; + } + + /** + * @param calendar + * the calendar to set + */ + public void setCalendar(Calendar calendar) + { + this.calendar = calendar; + } + +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBase.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBase.java new file mode 100644 index 000000000..ed3e4597d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBase.java @@ -0,0 +1,355 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import com.impetus.client.crud.BaseTest; +import com.impetus.client.persistence.CassandraCli; + +/** + * The Class StudentBase. + * + * @param + * the element type + */ +public abstract class StudentCassandraBase extends BaseTest +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public boolean AUTO_MANAGE_SCHEMA = true; + + /** The emf. */ + protected EntityManagerFactory emf; + + /** The em. */ + protected EntityManager em; + + // protected String persistenceUnit = + // /*"twissandra,twibase,twingo,picmysql"*/null; + + /** The student id1. */ + protected long studentId1; + + /** The student id2. */ + protected long studentId2; + + /** The student id3. */ + protected long studentId3; + + /** The enrolment date. */ + protected Date enrolmentDate = new Date(Long.parseLong("1344079065781")); + + /** The joining date and time. */ + protected Date joiningDateAndTime = new Date(); + + /** The date. */ + protected long date = new Date().getTime(); + + /** The new sql date. */ + protected java.sql.Date newSqlDate = new java.sql.Date(date); + + /** The enrolment time. */ + protected Date enrolmentTime = new Date(); + + /** The sql time. */ + protected java.sql.Time sqlTime = new java.sql.Time(date); + + /** The sql timestamp. */ + protected java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(date); + + /** The big decimal. */ + protected BigDecimal bigDecimal = new BigDecimal(123456789); + + /** The big integer. */ + protected BigInteger bigInteger = new BigInteger("123456789"); + + /** The number of students. */ + protected int numberOfStudents = 1000; + + /** The calendar. */ + protected Calendar calendar = Calendar.getInstance(); + + /** The dao. */ + // StudentDao dao; + + /** + * Sets the up internal. + * + * @param persisntenceUnit + * the new up internal + * @param CLQ_ENABLED + */ + protected void setupInternal(String persisntenceUnit, Map propertyMap, boolean CLQ_ENABLED) + { + // dao = new StudentDao(persistenceUnit); + + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + createSchema(CLQ_ENABLED); + } + else + { + CassandraCli.createKeySpace("KunderaExamples"); + } + + studentId1 = new Long(12345677); + studentId2 = new Long(12345678); + studentId3 = new Long(12345679); + + emf = Persistence.createEntityManagerFactory(persisntenceUnit, propertyMap); + em = emf.createEntityManager(); + } + + /** + * Sets the up internal. + * + * @param persistenceUnit + * the new up internal + */ + protected void teardownInternal(String persistenceUnit) + { + + if (RUN_IN_EMBEDDED_MODE) + { + stopServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + } + deleteSchema(); + + if (emf != null) + { + emf.close(); + } + } + + /** + * on insert. + * + * @param instance + * the instance + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + */ + protected void onInsert(E instance) throws InstantiationException, IllegalAccessException + { + + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", false, 10, 'A', (byte) 5, (short) 8, + (float) 69.3, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId2, 78575785898L, "Amresh", true, 20, 'B', (byte) 50, (short) 8, + (float) 69.2, 163.86765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, new BigInteger( + "123456788"), calendar, ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId3, 78575785899L, "Amresh", true, 15, 'C', (byte) 50, (short) 8, + (float) 61.6, 163.96765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, new BigInteger( + "123456787"), calendar, ((E) instance.getClass().newInstance()))); + + } + + /** + * Prepare data. + * + * @param studentId + * the student id + * @param uniqueId + * the unique id + * @param studentName + * the student name + * @param isExceptional + * the is exceptional + * @param age + * the age + * @param semester + * the semester + * @param digitalSignature + * the digital signature + * @param cgpa + * the cgpa + * @param percentage + * the percentage + * @param height + * the height + * @param enrolmentDate + * the enrolment date + * @param enrolmentTime + * the enrolment time + * @param joiningDateAndTime + * the joining date and time + * @param yearsSpent + * the years spent + * @param rollNumber + * the roll number + * @param monthlyFee + * the monthly fee + * @param newSqlDate + * the new sql date + * @param sqlTime + * the sql time + * @param sqlTimestamp + * the sql timestamp + * @param bigDecimal + * the big decimal + * @param bigInteger + * the big integer + * @param calendar + * the calendar + * @param o + * the o + * @return the person + */ + protected E prepareData(long studentId, long uniqueId, String studentName, boolean isExceptional, int age, + char semester, byte digitalSignature, short cgpa, float percentage, double height, + java.util.Date enrolmentDate, java.util.Date enrolmentTime, java.util.Date joiningDateAndTime, + Integer yearsSpent, Long rollNumber, Double monthlyFee, java.sql.Date newSqlDate, java.sql.Time sqlTime, + java.sql.Timestamp sqlTimestamp, BigDecimal bigDecimal, BigInteger bigInteger, Calendar calendar, E o) + { + o.setStudentId((Long) studentId); + o.setUniqueId(uniqueId); + o.setStudentName(studentName); + o.setExceptional(isExceptional); + o.setAge(age); + o.setSemester(semester); + o.setDigitalSignature(digitalSignature); + o.setCgpa(cgpa); + o.setPercentage(percentage); + o.setHeight(height); + + o.setEnrolmentDate(enrolmentDate); + o.setEnrolmentTime(enrolmentTime); + o.setJoiningDateAndTime(joiningDateAndTime); + + o.setYearsSpent(yearsSpent); + o.setRollNumber(rollNumber); + o.setMonthlyFee(monthlyFee); + o.setSqlDate(newSqlDate); + o.setSqlTime(sqlTime); + o.setSqlTimestamp(sqlTimestamp); + o.setBigDecimal(bigDecimal); + o.setBigInteger(bigInteger); + o.setCalendar(calendar); + return (E) o; + } + + /** + * Assert on data types. + * + * @param s + * the s + */ + protected void assertOnDataTypes(E s) + { + + Assert.assertNotNull(s); + Assert.assertEquals(((Long) studentId1).longValue(), s.getStudentId()); + Assert.assertEquals(78575785897L, s.getUniqueId()); + Assert.assertEquals("Amresh", s.getStudentName()); + Assert.assertEquals(false, s.isExceptional()); + Assert.assertEquals(10, s.getAge()); + Assert.assertEquals('A', s.getSemester()); + Assert.assertEquals((byte) 5, s.getDigitalSignature()); + Assert.assertEquals((short) 8, s.getCgpa()); + Assert.assertEquals((float) 69.3, s.getPercentage()); + Assert.assertEquals(163.76765654, s.getHeight()); + + Assert.assertEquals(enrolmentDate.getDate(), s.getEnrolmentDate().getDate()); + Assert.assertEquals(enrolmentDate.getMonth(), s.getEnrolmentDate().getMonth()); + Assert.assertEquals(enrolmentDate.getYear(), s.getEnrolmentDate().getYear()); + + Assert.assertEquals(enrolmentTime.getHours(), s.getEnrolmentTime().getHours()); + Assert.assertEquals(enrolmentTime.getMinutes(), s.getEnrolmentTime().getMinutes()); + Assert.assertEquals(enrolmentTime.getSeconds(), s.getEnrolmentTime().getSeconds()); + + Assert.assertEquals(joiningDateAndTime.getDate(), s.getJoiningDateAndTime().getDate()); + Assert.assertEquals(joiningDateAndTime.getMonth(), s.getJoiningDateAndTime().getMonth()); + Assert.assertEquals(joiningDateAndTime.getYear(), s.getJoiningDateAndTime().getYear()); + Assert.assertEquals(joiningDateAndTime.getHours(), s.getJoiningDateAndTime().getHours()); + Assert.assertEquals(joiningDateAndTime.getMinutes(), s.getJoiningDateAndTime().getMinutes()); + Assert.assertEquals(joiningDateAndTime.getSeconds(), s.getJoiningDateAndTime().getSeconds()); + + Assert.assertEquals(newSqlDate.getDate(), s.getSqlDate().getDate()); + Assert.assertEquals(newSqlDate.getMonth(), s.getSqlDate().getMonth()); + Assert.assertEquals(newSqlDate.getYear(), s.getSqlDate().getYear()); + + Assert.assertEquals(sqlTime.getMinutes(), s.getSqlTime().getMinutes()); + Assert.assertEquals(sqlTime.getSeconds(), s.getSqlTime().getSeconds()); + Assert.assertEquals(sqlTime.getHours(), s.getSqlTime().getHours()); + + Assert.assertEquals(sqlTimestamp.getDate(), s.getSqlTimestamp().getDate()); + Assert.assertEquals(sqlTimestamp.getMonth(), s.getSqlTimestamp().getMonth()); + Assert.assertEquals(sqlTimestamp.getYear(), s.getSqlTimestamp().getYear()); + Assert.assertEquals(sqlTimestamp.getHours(), s.getSqlTimestamp().getHours()); + Assert.assertEquals(sqlTimestamp.getMinutes(), s.getSqlTimestamp().getMinutes()); + Assert.assertEquals(sqlTimestamp.getSeconds(), s.getSqlTimestamp().getSeconds()); + + // Assert.assertEquals(Math.round(bigDecimal.doubleValue()), + // Math.round(s.getBigDecimal().doubleValue())); + Assert.assertEquals(bigInteger, s.getBigInteger()); + + Assert.assertEquals(calendar.get(Calendar.YEAR), s.getCalendar().get(Calendar.YEAR)); + Assert.assertEquals(calendar.get(Calendar.MONTH), s.getCalendar().get(Calendar.MONTH)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_YEAR), s.getCalendar().get(Calendar.WEEK_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_MONTH), s.getCalendar().get(Calendar.WEEK_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_MONTH), s.getCalendar().get(Calendar.DAY_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK), s.getCalendar().get(Calendar.DAY_OF_WEEK)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH), + s.getCalendar().get(Calendar.DAY_OF_WEEK_IN_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_YEAR), s.getCalendar().get(Calendar.DAY_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.HOUR), s.getCalendar().get(Calendar.HOUR)); + Assert.assertEquals(calendar.get(Calendar.HOUR_OF_DAY), s.getCalendar().get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(calendar.get(Calendar.AM), s.getCalendar().get(Calendar.AM)); + Assert.assertEquals(calendar.get(Calendar.PM), s.getCalendar().get(Calendar.PM)); + Assert.assertEquals(calendar.get(Calendar.AM_PM), s.getCalendar().get(Calendar.AM_PM)); + + Assert.assertEquals(new Integer(3), s.getYearsSpent()); + Assert.assertEquals(new Long(978423946455l), s.getRollNumber()); + Assert.assertEquals(new Double(135434.89), s.getMonthlyFee()); + + } + + abstract void startServer(); + + abstract void stopServer(); + + abstract void createSchema(boolean cLQ_ENABLED2); + + abstract void deleteSchema(); + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigDecimalTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigDecimalTest.java new file mode 100644 index 000000000..7b06333bb --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigDecimalTest.java @@ -0,0 +1,670 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.math.BigDecimal; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.datatypes.entities.StudentCassandraBigDecimal; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraBigDecimalTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + propertyMap = new HashMap(); + propertyMap.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_2_0); + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigDecimal + StudentCassandraBigDecimal studentMax = new StudentCassandraBigDecimal(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigDecimal) getMaxValue(BigDecimal.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigDecimal + StudentCassandraBigDecimal studentMin = new StudentCassandraBigDecimal(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((BigDecimal) getMinValue(BigDecimal.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigDecimal + StudentCassandraBigDecimal student = new StudentCassandraBigDecimal(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigDecimal) getRandomValue(BigDecimal.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBigDecimal studentMax = em + .find(StudentCassandraBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigDecimal studentMin = em + .find(StudentCassandraBigDecimal.class, getMinValue(BigDecimal.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigDecimal student = em + .find(StudentCassandraBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraBigDecimal student = em.find(StudentCassandraBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigDecimal newStudent = em + .find(StudentCassandraBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(BigDecimal.class)); + q.setParameter(2, getMaxValue(BigDecimal.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBigDecimal studentMax = em + .find(StudentCassandraBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraBigDecimal s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigDecimal newStudent = em.find(StudentCassandraBigDecimal.class, + getRandomValue(BigDecimal.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraBigDecimal s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigDecimal newStudent = em.find(StudentCassandraBigDecimal.class, + getRandomValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Amresh and s.age > " + + getMinValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigDecimal s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraBigDecimal s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraBigDecimal"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DecimalType"); + cfDef.setComparator_type("UTF8Type"); + + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "IntegerType"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraBigDecimal")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraBigDecimal"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigIntegerTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigIntegerTest.java new file mode 100644 index 000000000..19f8c9507 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBigIntegerTest.java @@ -0,0 +1,665 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraBigInteger; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraBigIntegerTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigInteger + StudentCassandraBigInteger studentMax = new StudentCassandraBigInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigInteger) getMaxValue(BigInteger.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigInteger + StudentCassandraBigInteger studentMin = new StudentCassandraBigInteger(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((BigInteger) getMinValue(BigInteger.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigInteger + StudentCassandraBigInteger student = new StudentCassandraBigInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigInteger) getRandomValue(BigInteger.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBigInteger studentMax = em + .find(StudentCassandraBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigInteger studentMin = em + .find(StudentCassandraBigInteger.class, getMinValue(BigInteger.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigInteger student = em + .find(StudentCassandraBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraBigInteger student = em.find(StudentCassandraBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigInteger newStudent = em + .find(StudentCassandraBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(BigInteger.class)); + q.setParameter(2, getMaxValue(BigInteger.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBigInteger studentMax = em + .find(StudentCassandraBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraBigInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigInteger newStudent = em.find(StudentCassandraBigInteger.class, + getRandomValue(BigInteger.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraBigInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBigInteger newStudent = em.find(StudentCassandraBigInteger.class, + getRandomValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Amresh and s.age > " + + getMinValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBigInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraBigInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraBigInteger"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("IntegerType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraBigInteger")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraBigInteger"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an BigInteger + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanPrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanPrimitiveTest.java new file mode 100644 index 000000000..929678a4a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanPrimitiveTest.java @@ -0,0 +1,637 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraBooleanPrimitive; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentCassandraBooleanPrimitiveTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of boolean + StudentCassandraBooleanPrimitive studentMax = new StudentCassandraBooleanPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of boolean + StudentCassandraBooleanPrimitive studentMin = new StudentCassandraBooleanPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Boolean) getMinValue(boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBooleanPrimitive studentMax = em.find(StudentCassandraBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanPrimitive studentMin = em.find(StudentCassandraBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraBooleanPrimitive student = em.find(StudentCassandraBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanPrimitive newStudent = em.find(StudentCassandraBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(boolean.class)); + q.setParameter(2, getMaxValue(boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Kuldeep or s.age > " + getMinValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for cassandra", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBooleanPrimitive studentMax = em.find(StudentCassandraBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMinValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraBooleanPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanPrimitive newStudent = em.find(StudentCassandraBooleanPrimitive.class, getRandomValue(boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraBooleanPrimitive s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanPrimitive newStudent = em.find(StudentCassandraBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Kuldeep and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.age = " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraBooleanPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraBooleanPrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("BooleanType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraBooleanPrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraBooleanPrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanWrapperTest.java new file mode 100644 index 000000000..bef9d173c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBooleanWrapperTest.java @@ -0,0 +1,638 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraBooleanWrapper; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentCassandraBooleanWrapperTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Boolean + StudentCassandraBooleanWrapper studentMax = new StudentCassandraBooleanWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(Boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Boolean + StudentCassandraBooleanWrapper studentMin = new StudentCassandraBooleanWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Boolean) getMinValue(Boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBooleanWrapper studentMax = em.find(StudentCassandraBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanWrapper studentMin = em.find(StudentCassandraBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraBooleanWrapper student = em.find(StudentCassandraBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanWrapper newStudent = em.find(StudentCassandraBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(Boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Boolean.class)); + q.setParameter(2, getMaxValue(Boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Kuldeep or s.age > " + getMinValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for cassandra", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(Boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(Boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBooleanWrapper studentMax = em.find(StudentCassandraBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMinValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(Boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraBooleanWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanWrapper newStudent = em.find(StudentCassandraBooleanWrapper.class, getRandomValue(Boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraBooleanWrapper s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBooleanWrapper newStudent = em.find(StudentCassandraBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Kuldeep and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + if (student.getId() == ((Boolean) getMaxValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.age = " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBooleanWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraBooleanWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraBooleanWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("BooleanType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraBooleanWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraBooleanWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBytePrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBytePrimitiveTest.java new file mode 100644 index 000000000..b899c4678 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraBytePrimitiveTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraBytePrimitive; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraBytePrimitiveTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of byte + StudentCassandraBytePrimitive studentMax = new StudentCassandraBytePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of byte + StudentCassandraBytePrimitive studentMin = new StudentCassandraBytePrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Byte) getMinValue(byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of byte + StudentCassandraBytePrimitive student = new StudentCassandraBytePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBytePrimitive studentMax = em.find(StudentCassandraBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBytePrimitive studentMin = em.find(StudentCassandraBytePrimitive.class, getMinValue(byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBytePrimitive student = em.find(StudentCassandraBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraBytePrimitive student = em.find(StudentCassandraBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBytePrimitive newStudent = em.find(StudentCassandraBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(byte.class)); + q.setParameter(2, getMaxValue(byte.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Byte) getMinValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraBytePrimitive studentMax = em.find(StudentCassandraBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraBytePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBytePrimitive newStudent = em.find(StudentCassandraBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraBytePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraBytePrimitive newStudent = em.find(StudentCassandraBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraBytePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraBytePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Byte) getMinValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraBytePrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraBytePrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraBytePrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraByteWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraByteWrapperTest.java new file mode 100644 index 000000000..a3f68a661 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraByteWrapperTest.java @@ -0,0 +1,667 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraByteWrapper; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraByteWrapperTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Byte + StudentCassandraByteWrapper studentMax = new StudentCassandraByteWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(Byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Byte + StudentCassandraByteWrapper studentMin = new StudentCassandraByteWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Byte) getMinValue(Byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Byte + StudentCassandraByteWrapper student = new StudentCassandraByteWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(Byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraByteWrapper studentMax = em.find(StudentCassandraByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraByteWrapper studentMin = em.find(StudentCassandraByteWrapper.class, getMinValue(Byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraByteWrapper student = em.find(StudentCassandraByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraByteWrapper student = em.find(StudentCassandraByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraByteWrapper newStudent = em.find(StudentCassandraByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.id between " + getMinValue(Byte.class) + " and " + + getMaxValue(Byte.class); + // query = + // "Select s From StudentCassandraByteWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + // q.setParameter(1, getMinValue(Byte.class)); + // q.setParameter(2, getMaxValue(Byte.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Byte.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraByteWrapper studentMax = em.find(StudentCassandraByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraByteWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraByteWrapper newStudent = em.find(StudentCassandraByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraByteWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraByteWrapper newStudent = em.find(StudentCassandraByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraByteWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraByteWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Byte.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraByteWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraByteWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraByteWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharTest.java new file mode 100644 index 000000000..624e83cf8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraChar; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraCharTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of char + StudentCassandraChar studentMax = new StudentCassandraChar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(char.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of char + StudentCassandraChar studentMin = new StudentCassandraChar(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Character) getMinValue(char.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of char + StudentCassandraChar student = new StudentCassandraChar(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(char.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraChar studentMax = em.find(StudentCassandraChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraChar studentMin = em.find(StudentCassandraChar.class, getMinValue(char.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraChar student = em.find(StudentCassandraChar.class, getRandomValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraChar student = em.find(StudentCassandraChar.class, getMaxValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraChar newStudent = em.find(StudentCassandraChar.class, getMaxValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(char.class)); + q.setParameter(2, getMaxValue(char.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraChar studentMax = em.find(StudentCassandraChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraChar.class, getMaxValue(char.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraChar s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraChar newStudent = em.find(StudentCassandraChar.class, getRandomValue(char.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraChar s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraChar newStudent = em.find(StudentCassandraChar.class, getRandomValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraChar s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraChar s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraChar"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("UTF8Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraChar")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraChar"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharacterTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharacterTest.java new file mode 100644 index 000000000..5693494ab --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraCharacterTest.java @@ -0,0 +1,666 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraCharacter; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraCharacterTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Character + StudentCassandraCharacter studentMax = new StudentCassandraCharacter(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(Character.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Character + StudentCassandraCharacter studentMin = new StudentCassandraCharacter(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Character) getMinValue(Character.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Character + StudentCassandraCharacter student = new StudentCassandraCharacter(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(Character.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraCharacter studentMax = em.find(StudentCassandraCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraCharacter studentMin = em.find(StudentCassandraCharacter.class, getMinValue(Character.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraCharacter student = em.find(StudentCassandraCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraCharacter student = em.find(StudentCassandraCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraCharacter newStudent = em.find(StudentCassandraCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Character.class)); + q.setParameter(2, getMaxValue(Character.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraCharacter studentMax = em.find(StudentCassandraCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraCharacter.class, getMaxValue(Character.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraCharacter s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraCharacter newStudent = em + .find(StudentCassandraCharacter.class, getRandomValue(Character.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraCharacter s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraCharacter newStudent = em + .find(StudentCassandraCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Amresh and s.age > " + + getMinValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraCharacter s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraCharacter s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraCharacter"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("UTF8Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraCharacter")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraCharacter"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDateTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDateTest.java new file mode 100644 index 000000000..0e88a6076 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDateTest.java @@ -0,0 +1,664 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraDate; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraDateTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentCassandraDate student = new StudentCassandraDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentCassandraDate studentMax = new StudentCassandraDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentCassandraDate studentMin = new StudentCassandraDate(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDate studentMax = em.find(StudentCassandraDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDate studentMin = em.find(StudentCassandraDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDate student = em.find(StudentCassandraDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraDate student = em.find(StudentCassandraDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDate newStudent = em.find(StudentCassandraDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Date.class)); + q.setParameter(2, getMaxValue(Date.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDate studentMax = em.find(StudentCassandraDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDate newStudent = em.find(StudentCassandraDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDate newStudent = em.find(StudentCassandraDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraDate"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DateType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraDate")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraDate"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoublePrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoublePrimitiveTest.java new file mode 100644 index 000000000..a0bad10cc --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoublePrimitiveTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraDoublePrimitive; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraDoublePrimitiveTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentCassandraDoublePrimitive studentMax = new StudentCassandraDoublePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentCassandraDoublePrimitive studentMin = new StudentCassandraDoublePrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentCassandraDoublePrimitive student = new StudentCassandraDoublePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDoublePrimitive studentMax = em.find(StudentCassandraDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoublePrimitive studentMin = em.find(StudentCassandraDoublePrimitive.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoublePrimitive student = em.find(StudentCassandraDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraDoublePrimitive student = em.find(StudentCassandraDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoublePrimitive newStudent = em.find(StudentCassandraDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(double.class)); + q.setParameter(2, getMaxValue(double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDoublePrimitive studentMax = em.find(StudentCassandraDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraDoublePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoublePrimitive newStudent = em.find(StudentCassandraDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraDoublePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoublePrimitive newStudent = em.find(StudentCassandraDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoublePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraDoublePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraDoublePrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DoubleType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraDoublePrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraDoublePrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an Double + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoubleWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoubleWrapperTest.java new file mode 100644 index 000000000..e1ee1bb30 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraDoubleWrapperTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraDoubleWrapper; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraDoubleWrapperTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentCassandraDoubleWrapper studentMax = new StudentCassandraDoubleWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentCassandraDoubleWrapper studentMin = new StudentCassandraDoubleWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentCassandraDoubleWrapper student = new StudentCassandraDoubleWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDoubleWrapper studentMax = em.find(StudentCassandraDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoubleWrapper studentMin = em.find(StudentCassandraDoubleWrapper.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoubleWrapper student = em.find(StudentCassandraDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraDoubleWrapper student = em.find(StudentCassandraDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoubleWrapper newStudent = em.find(StudentCassandraDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Double.class)); + q.setParameter(2, getMaxValue(Double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraDoubleWrapper studentMax = em.find(StudentCassandraDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraDoubleWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoubleWrapper newStudent = em.find(StudentCassandraDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraDoubleWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraDoubleWrapper newStudent = em.find(StudentCassandraDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraDoubleWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraDoubleWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraDoubleWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DoubleType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraDoubleWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraDoubleWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an Double + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatPrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatPrimitiveTest.java new file mode 100644 index 000000000..302f3db9a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatPrimitiveTest.java @@ -0,0 +1,666 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraFloatPrimitive; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraFloatPrimitiveTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of float + StudentCassandraFloatPrimitive studentMax = new StudentCassandraFloatPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of float + StudentCassandraFloatPrimitive studentMin = new StudentCassandraFloatPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Float) getMinValue(float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of float + StudentCassandraFloatPrimitive student = new StudentCassandraFloatPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraFloatPrimitive studentMax = em.find(StudentCassandraFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatPrimitive studentMin = em.find(StudentCassandraFloatPrimitive.class, getMinValue(float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatPrimitive student = em.find(StudentCassandraFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraFloatPrimitive student = em.find(StudentCassandraFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatPrimitive newStudent = em.find(StudentCassandraFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.id between " + getMinValue(float.class) + " and " + + getMaxValue(float.class); + // query = + // "Select s From StudentCassandraFloatPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + // q.setParameter(1, getMinValue(float.class)); + // q.setParameter(2, getMaxValue(float.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraFloatPrimitive studentMax = em.find(StudentCassandraFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraFloatPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatPrimitive newStudent = em.find(StudentCassandraFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraFloatPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatPrimitive newStudent = em.find(StudentCassandraFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraFloatPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraFloatPrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("FloatType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraFloatPrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraFloatPrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatWrapperTest.java new file mode 100644 index 000000000..b3c3ba4da --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraFloatWrapperTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraFloatWrapper; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraFloatWrapperTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Float + StudentCassandraFloatWrapper studentMax = new StudentCassandraFloatWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(Float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Float + StudentCassandraFloatWrapper studentMin = new StudentCassandraFloatWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Float) getMinValue(Float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Float + StudentCassandraFloatWrapper student = new StudentCassandraFloatWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(Float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraFloatWrapper studentMax = em.find(StudentCassandraFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatWrapper studentMin = em.find(StudentCassandraFloatWrapper.class, getMinValue(Float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatWrapper student = em.find(StudentCassandraFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraFloatWrapper student = em.find(StudentCassandraFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatWrapper newStudent = em.find(StudentCassandraFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Float.class)); + q.setParameter(2, getMaxValue(Float.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraFloatWrapper studentMax = em.find(StudentCassandraFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraFloatWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatWrapper newStudent = em.find(StudentCassandraFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraFloatWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraFloatWrapper newStudent = em.find(StudentCassandraFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraFloatWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraFloatWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraFloatWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("FloatType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraFloatWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraFloatWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntTest.java new file mode 100644 index 000000000..0a31623ae --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntTest.java @@ -0,0 +1,662 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraInt; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraIntTest extends CassandraBase +{ + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of int + StudentCassandraInt studentMax = new StudentCassandraInt(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(int.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of int + StudentCassandraInt studentMin = new StudentCassandraInt(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Integer) getMinValue(int.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of int + StudentCassandraInt student = new StudentCassandraInt(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(int.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraInt studentMax = em.find(StudentCassandraInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInt studentMin = em.find(StudentCassandraInt.class, getMinValue(int.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInt student = em.find(StudentCassandraInt.class, getRandomValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraInt student = em.find(StudentCassandraInt.class, getMaxValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInt newStudent = em.find(StudentCassandraInt.class, getMaxValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.id between " + getMinValue(int.class) + " and " + + getMaxValue(int.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Integer) getMinValue(int.class)).intValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraInt studentMax = em.find(StudentCassandraInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraInt.class, getMaxValue(int.class)); + Assert.assertNull(studentMax); + testPersist(useSameEm); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraInt s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInt newStudent = em.find(StudentCassandraInt.class, getRandomValue(int.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraInt s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInt newStudent = em.find(StudentCassandraInt.class, getRandomValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInt s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraInt s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Integer) getMinValue(int.class)).intValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraInt"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraInt")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraInt"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntegerTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntegerTest.java new file mode 100644 index 000000000..3f369c181 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraIntegerTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraInteger; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraIntegerTest extends CassandraBase +{ + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of integer + StudentCassandraInteger studentMax = new StudentCassandraInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(Integer.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of integer + StudentCassandraInteger studentMin = new StudentCassandraInteger(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Integer) getMinValue(Integer.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of integer + StudentCassandraInteger student = new StudentCassandraInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(Integer.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraInteger studentMax = em.find(StudentCassandraInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInteger studentMin = em.find(StudentCassandraInteger.class, getMinValue(Integer.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInteger student = em.find(StudentCassandraInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraInteger student = em.find(StudentCassandraInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInteger newStudent = em.find(StudentCassandraInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Integer.class)); + q.setParameter(2, getMaxValue(Integer.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Integer.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraInteger studentMax = em.find(StudentCassandraInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraInteger.class, getMaxValue(Integer.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInteger newStudent = em.find(StudentCassandraInteger.class, getRandomValue(Integer.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraInteger newStudent = em.find(StudentCassandraInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Integer.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraInteger"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraInteger")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraInteger"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongPrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongPrimitiveTest.java new file mode 100644 index 000000000..a3a2c58d2 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongPrimitiveTest.java @@ -0,0 +1,661 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraLongPrimitive; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraLongPrimitiveTest extends CassandraBase +{ + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of long + StudentCassandraLongPrimitive studentMax = new StudentCassandraLongPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of long + StudentCassandraLongPrimitive studentMin = new StudentCassandraLongPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Long) getMinValue(long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of long + StudentCassandraLongPrimitive student = new StudentCassandraLongPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraLongPrimitive studentMax = em.find(StudentCassandraLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongPrimitive studentMin = em.find(StudentCassandraLongPrimitive.class, getMinValue(long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongPrimitive student = em.find(StudentCassandraLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraLongPrimitive student = em.find(StudentCassandraLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongPrimitive newStudent = em.find(StudentCassandraLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.id between " + getMinValue(long.class) + " and " + + getMaxValue(long.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Long) getMinValue(long.class)).longValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraLongPrimitive studentMax = em.find(StudentCassandraLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraLongPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongPrimitive newStudent = em.find(StudentCassandraLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraLongPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongPrimitive newStudent = em.find(StudentCassandraLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraLongPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Long) getMinValue(long.class)).longValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraLongPrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("LongType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraLongPrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraLongPrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an long + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongWrapperTest.java new file mode 100644 index 000000000..8cad3379f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraLongWrapperTest.java @@ -0,0 +1,663 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraLongWrapper; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraLongWrapperTest extends CassandraBase +{ + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert min value of Long + StudentCassandraLongWrapper studentMin = new StudentCassandraLongWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Long) getMinValue(Long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Long + StudentCassandraLongWrapper student = new StudentCassandraLongWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(Long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Long + StudentCassandraLongWrapper studentMax = new StudentCassandraLongWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(Long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraLongWrapper studentMax = em.find(StudentCassandraLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongWrapper studentMin = em.find(StudentCassandraLongWrapper.class, getMinValue(Long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongWrapper student = em.find(StudentCassandraLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraLongWrapper student = em.find(StudentCassandraLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongWrapper newStudent = em.find(StudentCassandraLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Long.class)); + q.setParameter(2, getMaxValue(Long.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Long.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraLongWrapper studentMax = em.find(StudentCassandraLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraLongWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongWrapper newStudent = em.find(StudentCassandraLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraLongWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraLongWrapper newStudent = em.find(StudentCassandraLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraLongWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraLongWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Long.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraLongWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("LongType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraLongWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraLongWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an Long + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortPrimitiveTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortPrimitiveTest.java new file mode 100644 index 000000000..98c63ffbe --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortPrimitiveTest.java @@ -0,0 +1,660 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraShortPrimitive; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraShortPrimitiveTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentCassandraShortPrimitive studentMax = new StudentCassandraShortPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentCassandraShortPrimitive studentMin = new StudentCassandraShortPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Short) getMinValue(Short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentCassandraShortPrimitive student = new StudentCassandraShortPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraShortPrimitive studentMax = em.find(StudentCassandraShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortPrimitive studentMin = em.find(StudentCassandraShortPrimitive.class, getMinValue(Short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortPrimitive student = em.find(StudentCassandraShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraShortPrimitive student = em.find(StudentCassandraShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortPrimitive newStudent = em.find(StudentCassandraShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.id between " + getMinValue(Short.class) + " and " + + getMaxValue(Short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Short) getMinValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraShortPrimitive studentMax = em.find(StudentCassandraShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraShortPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortPrimitive newStudent = em.find(StudentCassandraShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraShortPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortPrimitive newStudent = em.find(StudentCassandraShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraShortPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Short) getMinValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraShortPrimitive"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + // CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraShortPrimitive")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraShortPrimitive"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an Short + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortWrapperTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortWrapperTest.java new file mode 100644 index 000000000..b17f2d8b1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraShortWrapperTest.java @@ -0,0 +1,662 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraShortWrapper; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraShortWrapperTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentCassandraShortWrapper studentMax = new StudentCassandraShortWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentCassandraShortWrapper studentMin = new StudentCassandraShortWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Short) getMinValue(Short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentCassandraShortWrapper student = new StudentCassandraShortWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraShortWrapper studentMax = em.find(StudentCassandraShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortWrapper studentMin = em.find(StudentCassandraShortWrapper.class, getMinValue(Short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortWrapper student = em.find(StudentCassandraShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraShortWrapper student = em.find(StudentCassandraShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortWrapper newStudent = em.find(StudentCassandraShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.id between " + getMinValue(Short.class) + " and " + + getMaxValue(Short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Short.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraShortWrapper studentMax = em.find(StudentCassandraShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraShortWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortWrapper newStudent = em.find(StudentCassandraShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraShortWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraShortWrapper newStudent = em.find(StudentCassandraShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraShortWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraShortWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Short.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraShortWrapper"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("Int32Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraShortWrapper")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraShortWrapper"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an Short + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraSqlDateTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraSqlDateTest.java new file mode 100644 index 000000000..b610c9907 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraSqlDateTest.java @@ -0,0 +1,665 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.sql.Date; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraSqlDate; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraSqlDateTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentCassandraSqlDate student = new StudentCassandraSqlDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentCassandraSqlDate studentMax = new StudentCassandraSqlDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentCassandraSqlDate studentMin = new StudentCassandraSqlDate(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraSqlDate studentMax = em.find(StudentCassandraSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraSqlDate studentMin = em.find(StudentCassandraSqlDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraSqlDate student = em.find(StudentCassandraSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraSqlDate student = em.find(StudentCassandraSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraSqlDate newStudent = em.find(StudentCassandraSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.id between " + getMinValue(Date.class) + " and " + + getMaxValue(Date.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraSqlDate studentMax = em.find(StudentCassandraSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraSqlDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraSqlDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraSqlDate newStudent = em.find(StudentCassandraSqlDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraSqlDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraSqlDate newStudent = em.find(StudentCassandraSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraSqlDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraSqlDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraSqlDate"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DateType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraSqlDate")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraSqlDate"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraStringTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraStringTest.java new file mode 100644 index 000000000..85b8ec3ee --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraStringTest.java @@ -0,0 +1,655 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraString; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraStringTest extends CassandraBase +{ + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of String + StudentCassandraString studentMax = new StudentCassandraString(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((String) getMaxValue(String.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of String + StudentCassandraString studentMin = new StudentCassandraString(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((String) getMinValue(String.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of String + StudentCassandraString student = new StudentCassandraString(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((String) getRandomValue(String.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraString studentMax = em.find(StudentCassandraString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraString studentMin = em.find(StudentCassandraString.class, getMinValue(String.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraString student = em.find(StudentCassandraString.class, getRandomValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraString student = em.find(StudentCassandraString.class, getMaxValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraString newStudent = em.find(StudentCassandraString.class, getMaxValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.id between " + getMinValue(String.class) + " and " + + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentCassandraString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraString studentMax = em.find(StudentCassandraString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraString.class, getMaxValue(String.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraString s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraString newStudent = em.find(StudentCassandraString.class, getRandomValue(String.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraString s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraString newStudent = em.find(StudentCassandraString.class, getRandomValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraString s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraString s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(String.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraString"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("UTF8Type"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraString")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraString"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an String + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTest.java new file mode 100644 index 000000000..5f0d009d4 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTest.java @@ -0,0 +1,937 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; + +/** + * The Class StudentDaoTest. script to create Cassandra column family for this + * test case: + * + * @see create column family STUDENT with comparator=AsciiType and + * key_validation_class=LongType and column_metadata=[{column_name: + * STUDENT_NAME, validation_class:UTF8Type, index_type: KEYS}, + * {column_name: AGE, validation_class:IntegerType, index_type: KEYS}, + * {column_name: UNIQUE_ID, validation_class:IntegerType, index_type: + * KEYS}, {column_name: IS_EXCEPTIONAL, validation_class:IntegerType, + * index_type: KEYS}, {column_name: SEMESTER, validation_class:IntegerType, + * index_type: KEYS}, {column_name: DIGITAL_SIGNATURE, + * validation_class:IntegerType, index_type: KEYS}, {column_name: CGPA, + * validation_class:IntegerType, index_type: KEYS}, {column_name: + * PERCENTAGE, validation_class:IntegerType, index_type: KEYS}, + * {column_name: HEIGHT, validation_class:IntegerType, index_type: KEYS}, + * {column_name: ENROLMENT_DATE, validation_class:IntegerType, index_type: + * KEYS}, {column_name: ENROLMENT_TIME, validation_class:IntegerType, + * index_type: KEYS}, {column_name: JOINING_DATE_TIME, + * validation_class:IntegerType, index_type: KEYS}, {column_name: + * YEARS_SPENT, validation_class:IntegerType, index_type: KEYS}, + * {column_name: ROLL_NUMBER, validation_class:IntegerType, index_type: + * KEYS}, {column_name: MONTHLY_FEE, validation_class:IntegerType, + * index_type: KEYS}, {column_name: SQL_DATE, validation_class:IntegerType, + * index_type: KEYS}, {column_name: SQL_TIMESTAMP, + * validation_class:IntegerType, index_type: KEYS}, {column_name: SQL_TIME, + * validation_class:IntegerType, index_type: KEYS}, {column_name: BIG_INT, + * validation_class:IntegerType, index_type: KEYS}, {column_name: + * BIG_DECIMAL, validation_class:IntegerType, index_type: KEYS}, + * {column_name: CALENDAR, validation_class:UTF8Type, index_type: KEYS}]; + * @author Vivek Mishra + */ +public class StudentCassandraTest extends StudentCassandraBase +{ + String persistenceUnit = "secIdxCassandraTest"; + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + protected Map propertyMap = null; + + protected boolean cqlEnabled = false; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + if (propertyMap == null) + { + propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + // propertyMap.put(CassandraConstants.CQL_VERSION, + // CassandraConstants.CQL_VERSION_2_0); + } + setupInternal(persistenceUnit, propertyMap, cqlEnabled); + propertyMap = null; + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + teardownInternal(persistenceUnit); + } + + @Test + @PerfTest(invocations = 2) + public void executeTests() + { + onInsert(); + onMerge(); + } + + /** + * Test method for. + * + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + * {@link com.impetus.kundera.examples.student.StudentDao#saveStudent(com.impetus.kundera.examples.crud.datatype.entities.StudentCassandra)} + * . + */ + + public void onInsert() + { + try + { + onInsert(new StudentCassandra()); + em.clear(); + // // find by id. + StudentEntityDef s = em.find(StudentCassandra.class, studentId1); + assertOnDataTypes((StudentCassandra) s); + em.clear(); + // + // // // find by name. + assertFindByName(em, "StudentCassandra", StudentCassandra.class, "Amresh", "studentName"); + em.clear(); + // + // // find by Id + // // assertFindByGTId(em, "StudentCassandra", + // StudentCassandra.class, + // // "12345677", "studentId"); + // + // // find by name and age. + assertFindByNameAndAge(em, "StudentCassandra", StudentCassandra.class, "Amresh", "10", "studentName"); + em.clear(); + // + // // find by name, age clause + assertFindByNameAndAgeGTAndLT(em, "StudentCassandra", StudentCassandra.class, "Amresh", "10", "20", + "studentName"); + em.clear(); + // // + // // // find by between clause + assertFindByNameAndAgeBetween(em, "StudentCassandra", StudentCassandra.class, "Amresh", "10", "15", + "studentName"); + em.clear(); + // + // // find by Range. + // assertFindByRange(em, "StudentCassandra", StudentCassandra.class, + // "12345677", "12345678", "studentId"); + // + // // find by without where clause. + assertFindWithoutWhereClause(em, "StudentCassandra", StudentCassandra.class); + em.clear(); + // + + // Query on Date. + String query = "Select s from StudentCassandra s where s.enrolmentDate =:enrolmentDate"; + Query q = em.createQuery(query); + q.setParameter("enrolmentDate", enrolmentDate); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + // Query on long. + /* String */query = "Select s from StudentCassandra s where s.uniqueId =?1"; + /* Query */q = em.createQuery(query); + q.setParameter(1, 78575785897L); + + /* List */results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + em.clear(); + // Assert on boolean. + query = "Select s from StudentCassandra s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, true); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(true, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + + em.clear(); + // with false. + query = "Select s from StudentCassandra s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, false); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + em.clear(); + // query on int. + + query = "Select s from StudentCassandra s where s.age =?1"; + q = em.createQuery(query); + q.setParameter(1, 10); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + em.clear(); + // query on char (semester) + + query = "Select s from StudentCassandra s where s.semester =?1"; + q = em.createQuery(query); + q.setParameter(1, 'A'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals('A', results.get(0).getSemester()); + em.clear(); + // query on float (percentage) + query = "Select s from StudentCassandra s where s.percentage =?1"; + q = em.createQuery(query); + q.setParameter(1, 61.6); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(true, results.get(0).isExceptional()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + em.clear(); + // query on double (height) + + query = "Select s from StudentCassandra s where s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + em.clear(); + // query on cgpa. + query = "Select s from StudentCassandra s where s.cgpa =?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + } + } + + em.clear(); + // query on yearsSpent. + Integer i = new Integer(3); + query = "Select s from StudentCassandra s where s.yearsSpent = 3"; + q = em.createQuery(query); + // q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + } + + em.clear(); + // query on yearsSpent. + query = "Select s from StudentCassandra s where s.yearsSpent =?1"; + q = em.createQuery(query); + q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + } + em.clear(); + // query on digitalSignature. + query = "Select s from StudentCassandra s where s.digitalSignature =?1"; + q = em.createQuery(query); + q.setParameter(1, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + } + } + em.clear(); + // query on cpga and digitalSignature. + query = "Select s from StudentCassandra s where s.cgpa =?1 and s.digitalSignature >= ?2 and s.digitalSignature <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 5, studentCassandra.getDigitalSignature()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + } + } + + em.clear(); + // query on cpga and digitalSignature. + query = "Select s from StudentCassandra s where s.digitalSignature = ?2 and s.cgpa >= ?3 and s.cgpa <=?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (short) 4); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + em.clear(); + + // query on percentage and height. + query = "Select s from StudentCassandra s where s.percentage >= ?2 and s.percentage <= ?3 and s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + q.setParameter(2, 61.6); + q.setParameter(3, 69.3); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(69.3f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + em.clear(); + // query on percentage and height parameter appended in string. + query = "Select s from StudentCassandra s where s.percentage >= 61.6 and s.percentage <= 69.3 and s.height = 163.76765654"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(69.3f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + em.clear(); + // query on cpga and digitalSignature parameter appended with String + // . + query = "Select s from StudentCassandra s where s.cgpa = 8 and s.digitalSignature >= 5 and s.digitalSignature <= 50"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 5, studentCassandra.getDigitalSignature()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + } + } + em.clear(); + // query on cpga and uniqueId. + query = "Select s from StudentCassandra s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 5, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785897L, studentCassandra.getUniqueId()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785898L, studentCassandra.getUniqueId()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785899L, studentCassandra.getUniqueId()); + } + } + + // query on cpga and semester. + query = "Select s from StudentCassandra s where s.cgpa =?1 and s.semester >= ?2 and s.semester < ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 'A'); + q.setParameter(3, 'C'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 5, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785897L, studentCassandra.getUniqueId()); + Assert.assertEquals(10, studentCassandra.getAge()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785898L, studentCassandra.getUniqueId()); + Assert.assertEquals(20, studentCassandra.getAge()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785899L, studentCassandra.getUniqueId()); + Assert.assertEquals(15, studentCassandra.getAge()); + } + } + + // query on cpga and semester with appending in string. + query = "Select s from StudentCassandra s where s.cgpa = 8 and s.semester >= A and s.semester < C"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + for (StudentCassandra studentCassandra : results) + { + if (studentCassandra.getStudentId() == studentId1) + { + Assert.assertEquals(false, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 5, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785897L, studentCassandra.getUniqueId()); + Assert.assertEquals(10, studentCassandra.getAge()); + } + else if (studentCassandra.getStudentId() == studentId2) + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785898L, studentCassandra.getUniqueId()); + Assert.assertEquals(20, studentCassandra.getAge()); + } + else + { + Assert.assertEquals(true, studentCassandra.isExceptional()); + Assert.assertEquals(8, studentCassandra.getCgpa()); + Assert.assertEquals(i, studentCassandra.getYearsSpent()); + Assert.assertEquals((byte) 50, studentCassandra.getDigitalSignature()); + Assert.assertEquals(78575785899L, studentCassandra.getUniqueId()); + Assert.assertEquals(15, studentCassandra.getAge()); + } + } + + em.clear(); + // query on invalid cpga and uniqueId. + query = "Select s from StudentCassandra s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 2); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + em.clear(); + // query on big integer. + query = "Select s from StudentCassandra s where s.bigInteger =?1"; + q = em.createQuery(query); + q.setParameter(1, bigInteger); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // invalid. + q.setParameter(1, new BigInteger("1234567823")); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + updateQueryTest(); + } + catch (Exception e) + { + e.printStackTrace(); + Assert.fail("Failure onInsert test, caused by :" + e); + } + } + + private void updateQueryTest() + { + Query q = em + .createQuery("update StudentCassandra s set s.studentName = :newName where s.studentName = :oldName"); + q.setParameter("newName", "NewAmresh"); + q.setParameter("oldName", "Amresh"); + q.executeUpdate(); + + em.clear(); + // // find by id. + StudentEntityDef s = em.find(StudentCassandra.class, studentId1); + Assert.assertEquals("NewAmresh", s.getStudentName()); + + q = em.createQuery("update StudentCassandra s set s.studentName = :newName where s.studentName = :oldName"); + q.setParameter("newName", "Amresh"); + q.setParameter("oldName", "NewAmresh"); + q.executeUpdate(); + + em.clear(); + // // find by id. + s = em.find(StudentCassandra.class, studentId1); + Assert.assertEquals("Amresh", s.getStudentName()); + } + + /** + * On merge. + */ + public void onMerge() + { + try + { + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", true, 10, 'C', (byte) 5, (short) 8, + (float) 69.6, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), + new Long(978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, + calendar, new StudentCassandra())); + StudentCassandra s = em.find(StudentCassandra.class, studentId1); + Assert.assertNotNull(s); + Assert.assertEquals("Amresh", s.getStudentName()); + // modify record. + s.setStudentName("NewAmresh"); + em.merge(s); + // emf.close(); + // assertOnMerge(em, "StudentCassandra", StudentCassandra.class, + // "Amresh", "NewAmresh", "STUDENT_NAME"); + Query q = em.createQuery("Select p from StudentCassandra p where p.studentName = NewAmresh"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + } + catch (Exception e) + { + Assert.fail("Failure onMerge test"); + } + + } + + /** + * Loads cassandra specific data. + * + * @param cql_enabled + * + * @throws TException + * @throws InvalidRequestException + * @throws UnavailableException + * @throws TimedOutException + * @throws SchemaDisagreementException + */ + private void loadData(boolean cql_enabled) throws TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "STUDENT"; + cfDef.keyspace = "KunderaExamples"; + cfDef.setKey_validation_class("LongType"); + cfDef.setComparator_type("UTF8Type"); + + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("UNIQUE_ID".getBytes()), "LongType"); + columnDef2.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef2); + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("STUDENT_NAME".getBytes()), "UTF8Type"); + columnDef3.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef3); + ColumnDef columnDef4 = new ColumnDef(ByteBuffer.wrap("IS_EXCEPTIONAL".getBytes()), "BooleanType"); + columnDef4.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef4); + ColumnDef columnDef5; + ColumnDef columnDef8; + ColumnDef columnDef11; + ColumnDef columnDef16; + ColumnDef columnDef7; + if (cql_enabled) + { + columnDef5 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + columnDef8 = new ColumnDef(ByteBuffer.wrap("CGPA".getBytes()), "Int32Type"); + columnDef11 = new ColumnDef(ByteBuffer.wrap("YEARS_SPENT".getBytes()), "Int32Type"); + columnDef16 = new ColumnDef(ByteBuffer.wrap("BIG_INT".getBytes()), "Int32Type"); + columnDef7 = new ColumnDef(ByteBuffer.wrap("DIGITAL_SIGNATURE".getBytes()), "Int32Type"); + } + else + { + columnDef5 = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "IntegerType"); + columnDef8 = new ColumnDef(ByteBuffer.wrap("CGPA".getBytes()), "IntegerType"); + columnDef11 = new ColumnDef(ByteBuffer.wrap("YEARS_SPENT".getBytes()), "IntegerType"); + columnDef16 = new ColumnDef(ByteBuffer.wrap("BIG_INT".getBytes()), "IntegerType"); + columnDef7 = new ColumnDef(ByteBuffer.wrap("DIGITAL_SIGNATURE".getBytes()), "BytesType"); + } + + columnDef5.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef5); + + columnDef8.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef8); + + columnDef11.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef11); + + columnDef16.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef16); + + ColumnDef columnDef6 = new ColumnDef(ByteBuffer.wrap("SEMESTER".getBytes()), "UTF8Type"); + columnDef6.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef6); + + columnDef7.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef7); + + ColumnDef columnDef9 = new ColumnDef(ByteBuffer.wrap("PERCENTAGE".getBytes()), "FloatType"); + columnDef9.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef9); + + ColumnDef columnDef10 = new ColumnDef(ByteBuffer.wrap("HEIGHT".getBytes()), "DoubleType"); + columnDef10.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef10); + + ColumnDef columnDef12 = new ColumnDef(ByteBuffer.wrap("ROLL_NUMBER".getBytes()), "LongType"); + columnDef12.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef12); + + ColumnDef columnDef13 = new ColumnDef(ByteBuffer.wrap("SQL_DATE".getBytes()), "DateType"); + columnDef13.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef13); + + ColumnDef columnDef14 = new ColumnDef(ByteBuffer.wrap("SQL_TIMESTAMP".getBytes()), "DateType"); + columnDef14.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef14); + + ColumnDef columnDef15 = new ColumnDef(ByteBuffer.wrap("SQL_TIME".getBytes()), "DateType"); + columnDef15.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef15); + + ColumnDef columnDef17 = new ColumnDef(ByteBuffer.wrap("BIG_DECIMAL".getBytes()), "DecimalType"); + columnDef17.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef17); + + ColumnDef columnDef18 = new ColumnDef(ByteBuffer.wrap("CALENDAR".getBytes()), "DateType"); + columnDef18.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef18); + + ColumnDef columnDef19 = new ColumnDef(ByteBuffer.wrap("MONTHLY_FEE".getBytes()), "DoubleType"); + columnDef19.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef19); + + ColumnDef columnDef20 = new ColumnDef(ByteBuffer.wrap("ENROLMENT_DATE".getBytes()), "DateType"); + columnDef20.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef20); + + ColumnDef columnDef21 = new ColumnDef(ByteBuffer.wrap("ENROLMENT_TIME".getBytes()), "DateType"); + columnDef21.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef21); + + ColumnDef columnDef22 = new ColumnDef(ByteBuffer.wrap("JOINING_DATE_TIME".getBytes()), "DateType"); + columnDef22.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(columnDef22); + + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace("KunderaExamples"); + CassandraCli.client.set_keyspace("KunderaExamples"); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("PERSONNEL")) + { + + CassandraCli.client.system_drop_column_family("PERSONNEL"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace("KunderaExamples"); + + } + + @Override + void startServer() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + @Override + void stopServer() + { + } + + @Override + void createSchema(boolean cql_enabled) + { + try + { + loadData(cql_enabled); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + @Override + void deleteSchema() + { + CassandraCli.dropKeySpace("KunderaExamples"); + } + + public void setPersistenceUnit(String persistenceUnit) + { + this.persistenceUnit = persistenceUnit; + } +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimeTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimeTest.java new file mode 100644 index 000000000..5e1a8bf6a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimeTest.java @@ -0,0 +1,665 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.sql.Time; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraTime; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraTimeTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentCassandraTime student = new StudentCassandraTime(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Time) getRandomValue(Time.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentCassandraTime studentMax = new StudentCassandraTime(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Time) getMaxValue(Time.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Time + StudentCassandraTime studentMin = new StudentCassandraTime(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Time) getMinValue(Time.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraTime studentMax = em.find(StudentCassandraTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTime studentMin = em.find(StudentCassandraTime.class, getMinValue(Time.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTime student = em.find(StudentCassandraTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraTime student = em.find(StudentCassandraTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTime newStudent = em.find(StudentCassandraTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.id between " + getMinValue(Time.class) + " and " + + getMaxValue(Time.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraTime studentMax = em.find(StudentCassandraTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraTime.class, getMaxValue(Time.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraTime s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTime newStudent = em.find(StudentCassandraTime.class, getRandomValue(Time.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentCassandraTime s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTime newStudent = em.find(StudentCassandraTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTime s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraTime s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Time) getRandomValue(Time.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraTime"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("DateType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraTime")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraTime"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimestampTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimestampTest.java new file mode 100644 index 000000000..221ff1beb --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraTimestampTest.java @@ -0,0 +1,668 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraTimestamp; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraTimestampTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentCassandraTimestamp student = new StudentCassandraTimestamp(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Timestamp) getRandomValue(Timestamp.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentCassandraTimestamp studentMax = new StudentCassandraTimestamp(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Timestamp) getMaxValue(Timestamp.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Timestamp + StudentCassandraTimestamp studentMin = new StudentCassandraTimestamp(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Timestamp) getMinValue(Timestamp.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraTimestamp studentMax = em.find(StudentCassandraTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTimestamp studentMin = em.find(StudentCassandraTimestamp.class, getMinValue(Timestamp.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTimestamp student = em.find(StudentCassandraTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraTimestamp student = em.find(StudentCassandraTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTimestamp newStudent = em.find(StudentCassandraTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.id between " + getMinValue(Timestamp.class) + + " and " + getMaxValue(Timestamp.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Kuldeep and s.age > " + + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Kuldeep and s.age > " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraTimestamp studentMax = em.find(StudentCassandraTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraTimestamp s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTimestamp newStudent = em + .find(StudentCassandraTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentCassandraTimestamp s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraTimestamp newStudent = em + .find(StudentCassandraTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Amresh and s.age > " + + getMinValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Kuldeep and s.age >= " + + getMinValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraTimestamp s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraTimestamp s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Timestamp) getRandomValue(Timestamp.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraTimestamp"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("LongType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraTimestamp")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraTimestamp"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraUUIDTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraUUIDTest.java new file mode 100644 index 000000000..088019e4f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentCassandraUUIDTest.java @@ -0,0 +1,677 @@ +package com.impetus.client.crud.datatypes; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentCassandraUUID; +import com.impetus.client.persistence.CassandraCli; + +public class StudentCassandraUUIDTest extends CassandraBase +{ + + private static final String keyspace = "KunderaCassandraDataType"; + + @Before + public void setUp() throws Exception + { + super.setUp(); + } + + @After + public void tearDown() throws Exception + { + super.tearDown(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNativeQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + /** + * @param b + */ + private void testNativeQuery(boolean b) + { + String s = "Select * From " + "\"StudentCassandraUUID\""; + EntityManager em = emf.createEntityManager(); + Query q = em.createNativeQuery(s, StudentCassandraUUID.class); + List results = q.getResultList(); + Assert.assertNotNull(results); + + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of UUID + StudentCassandraUUID studentMax = new StudentCassandraUUID(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((UUID) getMaxValue(UUID.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of UUID + StudentCassandraUUID studentMin = new StudentCassandraUUID(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((UUID) getMinValue(UUID.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of UUID + StudentCassandraUUID student = new StudentCassandraUUID(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((UUID) getRandomValue(UUID.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraUUID studentMax = em.find(StudentCassandraUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraUUID studentMin = em.find(StudentCassandraUUID.class, getMinValue(UUID.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraUUID student = em.find(StudentCassandraUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentCassandraUUID student = em.find(StudentCassandraUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraUUID newStudent = em.find(StudentCassandraUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.id between " + getMinValue(UUID.class) + " and " + + getMaxValue(UUID.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentCassandraUUID studentMax = em.find(StudentCassandraUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentCassandraUUID.class, getMaxValue(UUID.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentCassandraUUID s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraUUID newStudent = em.find(StudentCassandraUUID.class, getRandomValue(UUID.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentCassandraUUID s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentCassandraUUID newStudent = em.find(StudentCassandraUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentCassandraUUID s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentCassandraUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentCassandraUUID s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentCassandraUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + try + { + KsDef ksDef = null; + + CfDef cfDef = new CfDef(); + cfDef.name = "StudentCassandraUUID"; + cfDef.keyspace = keyspace; + cfDef.setKey_validation_class("UUIDType"); + cfDef.setComparator_type("UTF8Type"); + ColumnDef name = new ColumnDef(ByteBuffer.wrap("NAME".getBytes()), "UTF8Type"); + name.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(name); + ColumnDef age = new ColumnDef(ByteBuffer.wrap("AGE".getBytes()), "Int32Type"); + age.index_type = IndexType.KEYS; + cfDef.addToColumn_metadata(age); + List cfDefs = new ArrayList(); + cfDefs.add(cfDef); + try + { + CassandraCli.initClient(); + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("StudentCassandraUUID")) + { + + CassandraCli.client.system_drop_column_family("StudentCassandraUUID"); + + } + } + CassandraCli.client.system_add_column_family(cfDef); + + } + catch (NotFoundException e) + { + + ksDef = new KsDef(keyspace, "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an int + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + CassandraCli.client.set_keyspace(keyspace); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + + } + + public void dropSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java new file mode 100644 index 000000000..cac24ba99 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +/** + * @author vivek.mishra + * + */ +public interface StudentEntityDef +{ + + /** + * @return the studentId + */ + long getStudentId(); + + /** + * @param studentId + * the studentId to set + */ + void setStudentId(long studentId); + + /** + * @return the uniqueId + */ + long getUniqueId(); + + /** + * @param uniqueId + * the uniqueId to set + */ + void setUniqueId(long uniqueId); + + /** + * @return the studentName + */ + String getStudentName(); + + /** + * @param studentName + * the studentName to set + */ + void setStudentName(String studentName); + + /** + * @return the isExceptional + */ + boolean isExceptional(); + + /** + * @param isExceptional + * the isExceptional to set + */ + void setExceptional(boolean isExceptional); + + /** + * @return the age + */ + int getAge(); + + /** + * @param age + * the age to set + */ + void setAge(int age); + + /** + * @return the semester + */ + char getSemester(); + + /** + * @param semester + * the semester to set + */ + void setSemester(char semester); + + /** + * @return the digitalSignature + */ + byte getDigitalSignature(); + + /** + * @param digitalSignature + * the digitalSignature to set + */ + void setDigitalSignature(byte digitalSignature); + + /** + * @return the cgpa + */ + short getCgpa(); + + /** + * @param cgpa + * the cgpa to set + */ + void setCgpa(short cgpa); + + /** + * @return the percentage + */ + float getPercentage(); + + /** + * @param percentage + * the percentage to set + */ + void setPercentage(float percentage); + + /** + * @return the height + */ + double getHeight(); + + /** + * @param height + * the height to set + */ + void setHeight(double height); + + /** + * @return the enrolmentDate + */ + java.util.Date getEnrolmentDate(); + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + void setEnrolmentDate(java.util.Date enrolmentDate); + + /** + * @return the enrolmentTime + */ + java.util.Date getEnrolmentTime(); + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + void setEnrolmentTime(java.util.Date enrolmentTime); + + /** + * @return the joiningDateAndTime + */ + java.util.Date getJoiningDateAndTime(); + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + void setJoiningDateAndTime(java.util.Date joiningDateAndTime); + + /** + * @return the yearsSpent + */ + Integer getYearsSpent(); + + /** + * @param yearsSpent + * the yearsSpent to set + */ + void setYearsSpent(Integer yearsSpent); + + /** + * @return the rollNumber + */ + Long getRollNumber(); + + /** + * @param rollNumber + * the rollNumber to set + */ + void setRollNumber(Long rollNumber); + + /** + * @return the monthlyFee + */ + Double getMonthlyFee(); + + /** + * @param monthlyFee + * the monthlyFee to set + */ + void setMonthlyFee(Double monthlyFee); + + java.sql.Date getSqlDate(); + + void setSqlDate(java.sql.Date sqlDate); + + /** + * @return the sqlTimestamp + */ + java.sql.Timestamp getSqlTimestamp(); + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + void setSqlTimestamp(java.sql.Timestamp sqlTimestamp); + + /** + * @return the sqlTime + */ + java.sql.Time getSqlTime(); + + /** + * @param sqlTime + * the sqlTime to set + */ + void setSqlTime(java.sql.Time sqlTime); + + /** + * @return the bigInteger + */ + BigInteger getBigInteger(); + + /** + * @param bigInteger + * the bigInteger to set + */ + void setBigInteger(BigInteger bigInteger); + + /** + * @return the bigDecimal + */ + BigDecimal getBigDecimal(); + + /** + * @param bigDecimal + * the bigDecimal to set + */ + void setBigDecimal(BigDecimal bigDecimal); + + /** + * @return the calendar + */ + Calendar getCalendar(); + + /** + * @param calendar + * the calendar to set + */ + void setCalendar(Calendar calendar); + +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigDecimal.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigDecimal.java new file mode 100644 index 000000000..b1df811e6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigDecimal.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraBigDecimal", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraBigDecimal +{ + + @Id + private BigDecimal id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigDecimal getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigDecimal id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigInteger.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigInteger.java new file mode 100644 index 000000000..d53b349f7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBigInteger.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.math.BigInteger; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraBigInteger", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraBigInteger +{ + + @Id + private BigInteger id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigInteger getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigInteger id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanPrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanPrimitive.java new file mode 100644 index 000000000..02c537302 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanPrimitive.java @@ -0,0 +1,76 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraBooleanPrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraBooleanPrimitive +{ + @Id + private boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanWrapper.java new file mode 100644 index 000000000..f1cf08142 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBooleanWrapper.java @@ -0,0 +1,76 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraBooleanWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraBooleanWrapper +{ + @Id + private Boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBytePrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBytePrimitive.java new file mode 100644 index 000000000..ce6c48e7f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraBytePrimitive.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraBytePrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraBytePrimitive +{ + + @Id + private byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraByteWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraByteWrapper.java new file mode 100644 index 000000000..fa1351a0f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraByteWrapper.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraByteWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraByteWrapper +{ + + @Id + private Byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCalendar.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCalendar.java new file mode 100644 index 000000000..325ac4b6e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCalendar.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraCalendar", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraCalendar +{ + + @Id + private Calendar id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Calendar getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Calendar id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraChar.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraChar.java new file mode 100644 index 000000000..513d520c2 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraChar.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraChar", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraChar +{ + + @Id + private char id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public char getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(char id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCharacter.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCharacter.java new file mode 100644 index 000000000..9e3cf038c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraCharacter.java @@ -0,0 +1,76 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraCharacter", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraCharacter +{ + @Id + private Character id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Character getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Character id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDate.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDate.java new file mode 100644 index 000000000..a14ed7ecf --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDate.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraDate", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoublePrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoublePrimitive.java new file mode 100644 index 000000000..8bd72653a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoublePrimitive.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraDoublePrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraDoublePrimitive +{ + + @Id + private double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoubleWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoubleWrapper.java new file mode 100644 index 000000000..cc64dce9a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraDoubleWrapper.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraDoubleWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraDoubleWrapper +{ + + @Id + private Double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatPrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatPrimitive.java new file mode 100644 index 000000000..92d281fb4 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatPrimitive.java @@ -0,0 +1,76 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraFloatPrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraFloatPrimitive +{ + @Id + private float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatWrapper.java new file mode 100644 index 000000000..2a5d55bc2 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraFloatWrapper.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraFloatWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraFloatWrapper +{ + + @Id + private Float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInt.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInt.java new file mode 100644 index 000000000..9e48d4436 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInt.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraInt", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraInt +{ + + @Id + private int id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInteger.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInteger.java new file mode 100644 index 000000000..b8066bfec --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraInteger.java @@ -0,0 +1,76 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraInteger", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraInteger +{ + @Id + private Integer id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Integer getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Integer id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongPrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongPrimitive.java new file mode 100644 index 000000000..ba32310f6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongPrimitive.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraLongPrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraLongPrimitive +{ + + @Id + private long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongWrapper.java new file mode 100644 index 000000000..ccb0db76e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraLongWrapper.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraLongWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraLongWrapper +{ + + @Id + private Long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortPrimitive.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortPrimitive.java new file mode 100644 index 000000000..32a3f7825 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortPrimitive.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraShortPrimitive", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraShortPrimitive +{ + + @Id + private short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortWrapper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortWrapper.java new file mode 100644 index 000000000..801c864d9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraShortWrapper.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraShortWrapper", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraShortWrapper +{ + + @Id + private Short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraSqlDate.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraSqlDate.java new file mode 100644 index 000000000..02bae1ed0 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraSqlDate.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraSqlDate", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraSqlDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraString.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraString.java new file mode 100644 index 000000000..5d7f902e9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraString.java @@ -0,0 +1,77 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraString", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraString +{ + + @Id + private String id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTime.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTime.java new file mode 100644 index 000000000..ea818323e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTime.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Time; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraTime", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraTime +{ + + @Id + private Time id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Time getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Time id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTimestamp.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTimestamp.java new file mode 100644 index 000000000..34db6e537 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraTimestamp.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Timestamp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraTimestamp", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraTimestamp +{ + + @Id + private Timestamp id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Timestamp getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Timestamp id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraUUID.java b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraUUID.java new file mode 100644 index 000000000..49cb46dc8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/crud/datatypes/entities/StudentCassandraUUID.java @@ -0,0 +1,79 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "StudentCassandraUUID", schema = "KunderaCassandraDataType@CassandraDataTypeTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "name") }) +public class StudentCassandraUUID +{ + + @Id + private UUID id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public UUID getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(UUID id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/entity/CassandraUUIDEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/CassandraUUIDEntity.java new file mode 100644 index 000000000..0459beac3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/CassandraUUIDEntity.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.entity; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ +@Entity +@Table(name = "uuidsample", schema = "UUIDCassandra@cass_pu") +public class CassandraUUIDEntity +{ + @Id + @Column(name = "uuidKey") + private UUID uuidKey; + + @Column(name = "name") + private String name; + + @Column(name = "age") + private Integer age; + + /** + * Default constructor. + */ + public CassandraUUIDEntity() + { + + } + + /** + * @return the uuidKey + */ + public UUID getUuidKey() + { + return uuidKey; + } + + /** + * @param uuidKey + * the uuidKey to set + */ + public void setUuidKey(UUID uuidKey) + { + this.uuidKey = uuidKey; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(Integer age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/entity/PromoCode.java b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/PromoCode.java new file mode 100644 index 000000000..3be6f1e4b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/PromoCode.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.entity; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class PromoCode +{ + + @Column(name = "promoCode_id") + private String promoCodeId; + + @Column(name = "promoCode_name") + private String promoCodeName; + + public String getPromoCodeId() + { + return promoCodeId; + } + + public void setPromoCodeId(String promoCodeId) + { + this.promoCodeId = promoCodeId; + } + + public String getPromoCodeName() + { + return promoCodeName; + } + + public void setPromoCodeName(String promoCodeName) + { + this.promoCodeName = promoCodeName; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/entity/Users.java b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/Users.java new file mode 100644 index 000000000..e175d94db --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/entity/Users.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.entity; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "users", schema = "KunderaExamples@secIdxCassandraTest") +public class Users +{ + + @Id + protected String userId; + + @Column + protected String firstName = ""; + + @Column + protected String lastName = ""; + + @ElementCollection + private List promoCodes = new ArrayList(); + + public Users() + { + } + + public String getUserId() + { + return userId; + } + + public void setUserId(String userId) + { + this.userId = userId; + } + + public String getFirstName() + { + return firstName; + } + + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + public String getLastName() + { + return lastName; + } + + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public List getPromoCodes() + { + return promoCodes; + } + + public void setPromoCodes(List promoCodes) + { + this.promoCodes = promoCodes; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/CassandraGeneratedIdTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/CassandraGeneratedIdTest.java new file mode 100644 index 000000000..80b3aabde --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/CassandraGeneratedIdTest.java @@ -0,0 +1,227 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.generatedId; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.GenerationType; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.cassandra.thrift.ThriftClient; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdDefault; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdStrategyAuto; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdStrategyIdentity; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdStrategySequence; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdStrategyTable; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdWithOutSequenceGenerator; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdWithOutTableGenerator; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdWithSequenceGenerator; +import com.impetus.client.generatedId.entites.CassandraGeneratedIdWithTableGenerator; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.KunderaException; + +public class CassandraGeneratedIdTest +{ + EntityManagerFactory emf; + + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + emf = Persistence.createEntityManagerFactory("cassandra_generated_id"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + } + + @Test + public void testPersist() + { + EntityManager em = emf.createEntityManager(); + + CassandraGeneratedIdDefault idDefault = new CassandraGeneratedIdDefault(); + idDefault.setName("kuldeep"); + try + { + em.persist(idDefault); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals("java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.AUTO + " Strategy not supported by this client :" + ThriftClient.class.getName(), + e.getMessage()); + } + CassandraGeneratedIdStrategyAuto strategyAuto = new CassandraGeneratedIdStrategyAuto(); + strategyAuto.setName("kuldeep"); + try + { + em.persist(strategyAuto); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals("java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.AUTO + " Strategy not supported by this client :" + ThriftClient.class.getName(), + e.getMessage()); + } + + CassandraGeneratedIdStrategyIdentity strategyIdentity = new CassandraGeneratedIdStrategyIdentity(); + strategyIdentity.setName("kuldeep"); + try + { + em.persist(strategyIdentity); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.UnsupportedOperationException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.IDENTITY + " Strategy not supported by this client :" + + ThriftClient.class.getName(), e.getMessage()); + } + + CassandraGeneratedIdStrategySequence strategySequence = new CassandraGeneratedIdStrategySequence(); + strategySequence.setName("Kuldeep"); + try + { + em.persist(strategySequence); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + ThriftClient.class.getName(), e.getMessage()); + } + + CassandraGeneratedIdStrategyTable strategyTable = new CassandraGeneratedIdStrategyTable(); + strategyTable.setName("KK"); + try + { + em.persist(strategyTable); + List list = em.createQuery( + "Select c from CassandraGeneratedIdStrategyTable c").getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("KK", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + strategyTable = em.find(CassandraGeneratedIdStrategyTable.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("KK", strategyTable.getName()); + + } + catch (KunderaException e) + { + Assert.fail(); + } + + CassandraGeneratedIdWithOutSequenceGenerator withOutSequenceGenerator = new CassandraGeneratedIdWithOutSequenceGenerator(); + withOutSequenceGenerator.setName("Kuldeep Kumar"); + try + { + em.persist(withOutSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + ThriftClient.class.getName(), e.getMessage()); + } + + CassandraGeneratedIdWithOutTableGenerator withOutTableGenerator = new CassandraGeneratedIdWithOutTableGenerator(); + withOutTableGenerator.setName("Kuldeep Mishra"); + try + { + em.persist(withOutTableGenerator); + List list = em.createQuery( + "Select c from CassandraGeneratedIdWithOutTableGenerator c").getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("Kuldeep Mishra", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + withOutTableGenerator = em.find(CassandraGeneratedIdWithOutTableGenerator.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("Kuldeep Mishra", withOutTableGenerator.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + CassandraGeneratedIdWithSequenceGenerator withSequenceGenerator = new CassandraGeneratedIdWithSequenceGenerator(); + withSequenceGenerator.setName("Kuldeep Kumar Mishra"); + try + { + em.persist(withSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + ThriftClient.class.getName(), e.getMessage()); + } + CassandraGeneratedIdWithTableGenerator withTableGenerator = new CassandraGeneratedIdWithTableGenerator(); + withTableGenerator.setName("Kumar Mishra"); + try + { + em.persist(withTableGenerator); + List list = em.createQuery( + "Select c from CassandraGeneratedIdWithTableGenerator c").getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("Kumar Mishra", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + withTableGenerator = em.find(CassandraGeneratedIdWithTableGenerator.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("Kumar Mishra", withTableGenerator.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdDefault.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdDefault.java new file mode 100644 index 000000000..7d2f482ab --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdDefault.java @@ -0,0 +1,53 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdDefault", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdDefault +{ + @Id + @GeneratedValue + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyAuto.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyAuto.java new file mode 100644 index 000000000..152efbb31 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyAuto.java @@ -0,0 +1,57 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "CassandraGeneratedIdStrategyAuto", schema = "kunderaGeneratedId@cassandra_generated_id") +@TableGenerator(name = "id_gen") +public class CassandraGeneratedIdStrategyAuto +{ + @Id + @GeneratedValue(generator = "id_gen", strategy = GenerationType.AUTO) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyIdentity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyIdentity.java new file mode 100644 index 000000000..d13212471 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyIdentity.java @@ -0,0 +1,71 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdStrategyIdentity", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdStrategyIdentity +{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategySequence.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategySequence.java new file mode 100644 index 000000000..56b7948c5 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategySequence.java @@ -0,0 +1,57 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdStrategySequence", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdStrategySequence +{ + @Id + @SequenceGenerator(name = "seq_gen") + @GeneratedValue(generator = "seq_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyTable.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyTable.java new file mode 100644 index 000000000..b25146e8c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdStrategyTable.java @@ -0,0 +1,59 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "CassandraGeneratedIdStrategyTable", schema = "kunderaGeneratedId@cassandra_generated_id") +@TableGenerator(name = "table_gen") +public class CassandraGeneratedIdStrategyTable +{ + + @Id + @TableGenerator(name = "table_gen_1") + @GeneratedValue(generator = "table_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutSequenceGenerator.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutSequenceGenerator.java new file mode 100644 index 000000000..d76b4f722 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdWithOutSequenceGenerator", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdWithOutSequenceGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutTableGenerator.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutTableGenerator.java new file mode 100644 index 000000000..d73f6a347 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithOutTableGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdWithOutTableGenerator", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdWithOutTableGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithSequenceGenerator.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithSequenceGenerator.java new file mode 100644 index 000000000..3f532add3 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraGeneratedIdWithSequenceGenerator", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdWithSequenceGenerator +{ + @Id + @SequenceGenerator(name = "id_gen", allocationSize = 20, initialValue = 80, schema = "kunderaGeneratedId", sequenceName = "newSequence") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithTableGenerator.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithTableGenerator.java new file mode 100644 index 000000000..8c273a20a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/CassandraGeneratedIdWithTableGenerator.java @@ -0,0 +1,57 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "CassandraGeneratedIdWithTableGenerator", schema = "kunderaGeneratedId@cassandra_generated_id") +public class CassandraGeneratedIdWithTableGenerator +{ + + @Id + @TableGenerator(name = "id_gen", allocationSize = 30, initialValue = 100, schema = "kunderaGeneratedId", table = "kundera", pkColumnName = "sequence", valueColumnName = "sequenceValue", pkColumnValue = "kk") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeAddress.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeAddress.java new file mode 100644 index 000000000..bb275679c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeAddress.java @@ -0,0 +1,65 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "EmployeeAddress", schema = "kunderaGeneratedId@cassandra_generated_id") +public class EmployeeAddress +{ + + @Id + @Column(name = "RegionID") + @TableGenerator(name = "id_gen", allocationSize = 1, initialValue = 1) + @GeneratedValue(generator = "id_gen", strategy = GenerationType.TABLE) + private Long address; + + @Column(name="street") + private String street; + + public EmployeeAddress() + { + + } + public Long getAddress() + { + return address; + } + + public void setAddress(Long address) + { + this.address = address; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfo.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfo.java new file mode 100644 index 000000000..5e243f208 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfo.java @@ -0,0 +1,84 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.generatedId.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "EmployeeInfo", schema = "kunderaGeneratedId@cassandra_generated_id") +public class EmployeeInfo +{ + @Id + @Column(name = "UserID") + @TableGenerator(name = "id_gen", allocationSize = 1, initialValue = 1) + @GeneratedValue(generator = "id_gen", strategy = GenerationType.TABLE) + private Long userid; + +// @Column(name="name") +// +// private String employeeName; + + public EmployeeInfo() + { + + } + + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "address_id") + private EmployeeAddress address; + + public Long getUserid() + { + return userid; + } + + public void setUserid(Long userid) + { + this.userid = userid; + } + + public EmployeeAddress getAddress() + { + return address; + } + + public void setAddress(EmployeeAddress address) + { + this.address = address; + } + +// public String getEmployeeName() +// { +// return employeeName; +// } +// +// public void setEmployeeName(String employeeName) +// { +// this.employeeName = employeeName; +// } +// + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfoTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfoTest.java new file mode 100644 index 000000000..1ca5280a6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/generatedId/entites/EmployeeInfoTest.java @@ -0,0 +1,87 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.generatedId.entites; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +public class EmployeeInfoTest +{ + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + emf = Persistence.createEntityManagerFactory("cassandra_generated_id"); + } + + @Test + public void test() + { + EntityManager em = emf.createEntityManager(); + EmployeeInfo emp_info = new EmployeeInfo(); + EmployeeAddress address_info = new EmployeeAddress(); + address_info.setStreet("street"); + emp_info.setAddress(address_info); +// emp_info.setEmployeeName("vivek"); + em.persist(emp_info); + + em.clear(); + + EmployeeInfo result = em.find(EmployeeInfo.class, 1l); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getAddress()); + Assert.assertNotNull(result.getAddress().getStreet()); + Assert.assertNotNull(result.getAddress().getAddress()); + Assert.assertEquals("street", result.getAddress().getStreet()); + + result.getAddress().setStreet("newStreet"); + em.merge(result); + + em.clear(); + + result = em.find(EmployeeInfo.class, 1l); + Assert.assertNotNull(result); + Assert.assertNotNull(result.getAddress()); + Assert.assertNotNull(result.getAddress().getStreet()); + Assert.assertNotNull(result.getAddress().getAddress()); + Assert.assertEquals("newStreet", result.getAddress().getStreet()); + + em.remove(result); + em.clear(); + result = em.find(EmployeeInfo.class, 1l); + Assert.assertNull(result); + + } + + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("kunderaGeneratedId"); + emf.close(); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/junit/TestCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/junit/TestCassandra.java new file mode 100644 index 000000000..ea62f2c9e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/junit/TestCassandra.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.junit; + +import java.nio.ByteBuffer; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.log4j.Logger; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.entity.CassandraUUIDEntity; +import com.impetus.client.persistence.CassandraCli; + +/** + * Test case for CRUD operations on Cassandra database using Kundera. + */ +public class TestCassandra +{ + /** The logger. */ + private static Logger logger = Logger.getLogger(TestCassandra.class); + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + logger.info("starting server"); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("UUIDCassandra"); + Cassandra.Client client = CassandraCli.getClient(); + client.set_keyspace("UUIDCassandra"); + CfDef cf_def = new CfDef(); + cf_def.keyspace = "UUIDCassandra"; + cf_def.name = "uuidsample"; + cf_def.setKey_validation_class("UUIDType"); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("name".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + cf_def.addToColumn_metadata(columnDef2); + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("age".getBytes()), "Int32Type"); + columnDef3.index_type = IndexType.KEYS; + cf_def.addToColumn_metadata(columnDef3); + client.system_add_column_family(cf_def); + } + + @Test + public void testUUID() + { + EntityManagerFactory emf = Persistence.createEntityManagerFactory("cass_pu"); + UUID key = UUID.randomUUID(); + CassandraUUIDEntity entity = new CassandraUUIDEntity(); + entity.setAge(10); + entity.setName("vivek"); + entity.setUuidKey(key); + + EntityManager em = emf.createEntityManager(); + em.persist(entity); + CassandraUUIDEntity result = em.find(CassandraUUIDEntity.class, key); + Assert.assertNotNull(result); + Assert.assertEquals(key, result.getUuidKey()); + Assert.assertEquals("vivek", result.getName()); + Assert.assertEquals(new Integer(10), result.getAge()); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + logger.info("destroying"); + CassandraCli.dropKeySpace("UUIDCassandra"); + } +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraBatchEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraBatchEntity.java new file mode 100644 index 000000000..055cbe35d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraBatchEntity.java @@ -0,0 +1,98 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.persistence; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class + * + * @author amresh.singh + */ +@Entity +@Table(name = "CassandraBatchEntity", schema = "kunderaexamples@cassandra") +public class CassandraBatchEntity +{ + @Id + @Column(name = "user_name") + private String user_name; + + @Column(name = "password") + private String password; + + @Column(name = "name") + private String name; + + public CassandraBatchEntity() + { + + } + + /** + * @return the user_name + */ + public String getUser_name() + { + return user_name; + } + + /** + * @param user_name + * the user_name to set + */ + public void setUser_name(String user_name) + { + this.user_name = user_name; + } + + /** + * @return the password + */ + public String getPassword() + { + return password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraCli.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraCli.java new file mode 100644 index 000000000..3b88b7e58 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraCli.java @@ -0,0 +1,368 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.persistence; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.Socket; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.service.EmbeddedCassandraService; +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.Compression; +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.transport.TFramedTransport; +import org.apache.thrift.transport.TSocket; +import org.apache.thrift.transport.TTransport; +import org.apache.thrift.transport.TTransportException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaException; + +/** + * The Class CassandraCli. + * + * @author vivek.mishra + */ +public final class CassandraCli +{ + + /** The cassandra. */ + private static EmbeddedCassandraService cassandra; + + /** The client. */ + public static Cassandra.Client client; + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(CassandraCli.class); + + /** + * Cassandra set up. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + public static void cassandraSetUp() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + if (!checkIfServerRunning()) + { + cassandra = new EmbeddedCassandraService(); + cassandra.start(); + } + initClient(); + } + + /** + * Create keyspace. + * + * @param keyspaceName + * keyspace name. + */ + public static void createKeySpace(String keyspaceName) + { + try + { + client.describe_keyspace(keyspaceName); + } + catch (NotFoundException e) + { + List cfDefs = new ArrayList(); + KsDef ks_Def = new KsDef(keyspaceName, SimpleStrategy.class.getName(), cfDefs); + + // Set replication factor + if (ks_Def.strategy_options == null) + { + ks_Def.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ks_Def.strategy_options.put("replication_factor", "1"); + + try + { + client.system_add_keyspace(ks_Def); + } + catch (TException e1) + { + log.error("Error while adding keyspace, Caused by: .", e1); + } + catch (InvalidRequestException ess) + { + log.error("Error while adding keyspace, Caused by: .", ess); + } + catch (SchemaDisagreementException sde) + { + log.error("Error while adding keyspace, Caused by: .", sde); + } + + } + + catch (InvalidRequestException e) + { + log.error("Error while adding keyspace, Caused by: .", e); + } + catch (TException e) + { + log.error("Error while adding keyspace, Caused by: .", e); + } + + } + + public static void truncateColumnFamily(String keyspace, String... columns) + { + try + { + if (client != null) + { + client.set_keyspace(keyspace); + for (String column : columns) + { + if (columnFamilyExist(column, keyspace)) + { + client.truncate(column); + } + } + } + } + catch (IllegalArgumentException iex) + { + // do nothing. + } + catch (InvalidRequestException e) + { + // do nothing. + } + catch (UnavailableException e) + { + // do nothing. + } + catch (TimedOutException e) + { + // do nothing. + } + catch (TException e) + { + // do nothing. + } + } + + /** + * Drop out key space. + * + * @param keyspaceName + * keyspace name + */ + public static void dropKeySpace(String keyspaceName) + { + try + { + if (client != null) + { + client.system_drop_keyspace(keyspaceName); + } + // deleteCassandraFolders("/var/lib/cassandra/data/"); + // deleteCassandraFolders("/var/lib/cassandra/data/system/"); + // deleteCassandraFolders("/var/lib/cassandra/commitlog/"); + // deleteCassandraFolders("/var/lib/cassandra/saved_caches/"); + // deleteCassandraFolders("/var/log/cassandra/"); + } + catch (InvalidRequestException e) + { + return; + } + catch (SchemaDisagreementException e) + { + log.error("Error while dropping keyspace, Caused by: .", e); + } + catch (TException e) + { + log.error("Error while dropping keyspace, Caused by: .", e); + } + } + + private static void deleteCassandraFolders(String dir) + { + // System.out.println("Cleaning up folder " + dir); + File directory = new File(dir); + // Get all files in directory + File[] files = directory.listFiles(); + for (File file : files) + { + // Delete each file + if (!file.delete()) + { + // Failed to delete file + // System.out.println("Failed to delete " + file); + } + } + } + + public static boolean keyspaceExist(String keySpaceName) + { + try + { + return client.describe_keyspace(keySpaceName) != null; + } + catch (NotFoundException e) + { + return false; + } + catch (InvalidRequestException e) + { + log.error("Error while keyspace check, Caused by: .", e); + } + catch (TException e) + { + log.error("Error while keyspace check, Caused by: .", e); + } + return false; + } + + public static boolean columnFamilyExist(String columnfamilyName, String keyspaceName) + { + try + { + client.set_keyspace(keyspaceName); + client.system_add_column_family(new CfDef(keyspaceName, columnfamilyName)); + } + catch (InvalidRequestException e) + { + return true; + } + catch (SchemaDisagreementException e) + { + return false; + } + catch (TException e) + { + return false; + } + return false; + } + + /** + * Check if server running. + * + * @return true, if successful + */ + private static boolean checkIfServerRunning() + { + try + { + Socket socket = new Socket("127.0.0.1", 9160); + return socket.getInetAddress() != null; + } + catch (UnknownHostException e) + { + return false; + } + catch (IOException e) + { + return false; + } + + } + + /** + * Inits the client. + * + * @throws TTransportException + * the t transport exception + */ + public static void initClient() throws TTransportException + { + TSocket socket = new TSocket("127.0.0.1", 9160); + TTransport transport = new TFramedTransport(socket); + TProtocol protocol = new TBinaryProtocol(transport); + client = new Cassandra.Client(protocol); + socket.open(); + } + + /** + * @return the client + */ + public static Cassandra.Client getClient() + { + return client; + } + + public static void executeCqlQuery(String cqlQuery) + { + try + { + getClient().set_cql_version("3.0.0"); + getClient().execute_cql3_query(ByteBuffer.wrap(cqlQuery.getBytes("UTF-8")), Compression.NONE, + ConsistencyLevel.ONE); + } + catch (InvalidRequestException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + catch (UnavailableException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + catch (TimedOutException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + catch (SchemaDisagreementException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + catch (TException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + catch (UnsupportedEncodingException e) + { + log.error("Error while executing cql query {}, Caused by: .", cqlQuery, e); + throw new KunderaException(e); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntity.java new file mode 100644 index 000000000..329fec946 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntity.java @@ -0,0 +1,113 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.persistence; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class + * + * @author amresh.singh + */ +@Entity +@Table(name = "users", schema = "kunderaexamples@cassandra") +public class CassandraEntity +{ + @Id + @Column(name = "key") + private String key; + + @Column(name = "full_name") + private String full_name; + + @Column(name = "birth_date") + private Integer birth_date; + + @Column(name = "state") + private String state; + + /** + * @return the key + */ + public String getKey() + { + return key; + } + + /** + * @param key + * the key to set + */ + public void setKey(String key) + { + this.key = key; + } + + /** + * @return the full_name + */ + public String getFull_name() + { + return full_name; + } + + /** + * @param full_name + * the full_name to set + */ + public void setFull_name(String full_name) + { + this.full_name = full_name; + } + + /** + * @return the birth_date + */ + public Integer getBirth_date() + { + return birth_date; + } + + /** + * @param birth_date + * the birth_date to set + */ + public void setBirth_date(int birth_date) + { + this.birth_date = birth_date; + } + + /** + * @return the state + */ + public String getState() + { + return state; + } + + /** + * @param state + * the state to set + */ + public void setState(String state) + { + this.state = state; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntitySample.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntitySample.java new file mode 100644 index 000000000..03633ff5e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/CassandraEntitySample.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.persistence; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Test Entity + * + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "users", schema = "KunderaExamples@cassandra") +// @NamedQuery(name="delete.query",query="Delete From CassandraEntitySample c where c.state=UP") +public class CassandraEntitySample +{ + + @Id + @Column(name = "key") + private String key; + + @Column(name = "full_name") + private String full_name; + + @Column(name = "birth_date") + private Integer birth_date; + + @Column(name = "state") + private String state; + + /** + * @return the key + */ + public String getKey() + { + return key; + } + + /** + * @param key + * the key to set + */ + public void setKey(String key) + { + this.key = key; + } + + /** + * @return the full_name + */ + public String getFull_name() + { + return full_name; + } + + /** + * @param full_name + * the full_name to set + */ + public void setFull_name(String full_name) + { + this.full_name = full_name; + } + + /** + * @return the birth_date + */ + public Integer getBirth_date() + { + return birth_date; + } + + /** + * @param birth_date + * the birth_date to set + */ + public void setBirth_date(int birth_date) + { + this.birth_date = birth_date; + } + + /** + * @return the state + */ + public String getState() + { + return state; + } + + /** + * @param state + * the state to set + */ + public void setState(String state) + { + this.state = state; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/EntityManagerFactoryImplTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/EntityManagerFactoryImplTest.java new file mode 100644 index 000000000..87c6af7e1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/EntityManagerFactoryImplTest.java @@ -0,0 +1,197 @@ +/** + * + */ +package com.impetus.client.persistence; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * @author Kuldeep Mishra + * + */ +public class EntityManagerFactoryImplTest +{ + + /** + * + */ + private static final String _KEYSPACE2 = "KunderaExamples"; + + /** + * + */ + private static final String _KEYSPACE1 = "UUIDCassandra"; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(_KEYSPACE1); + CassandraCli.createKeySpace(_KEYSPACE2); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(_KEYSPACE1); + CassandraCli.dropKeySpace(_KEYSPACE2); + } + + @Test + public void test() + { + String _PU1 = "cass_pu"; + String _PU2 = "secIdxCassandraTest"; + EntityManagerFactory emf1 = Persistence.createEntityManagerFactory(_PU1); + checkEMFPropertiesAfterCreating(_PU1, emf1); + emf1.close(); + checkEMFPropertyAfterClosing(_PU1, emf1); + + EntityManagerFactory emf2 = Persistence.createEntityManagerFactory(_PU2); + checkEMFPropertiesAfterCreating(_PU2, emf2); + emf2.close(); + checkEMFPropertyAfterClosing(_PU2, emf2); + + emf1 = Persistence.createEntityManagerFactory(_PU1); + checkEMFPropertiesAfterCreating(_PU1, emf1); + + emf2 = Persistence.createEntityManagerFactory(_PU2); + checkEMFPropertiesAfterCreating(_PU2, emf2); + + emf1.close(); + checkEMFPropertyAfterClosing(_PU1, emf1); + + checkEMFPropertiesAfterCreating(_PU2, emf2); + + emf2.close(); + checkEMFPropertyAfterClosing(_PU2, emf2); + + // On concurrent testing + + // create first emf + OnConcurrentEMF c1 = new OnConcurrentEMF(_PU1, "emf1"); + try + { + c1.t.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + Assert.assertEquals("emf1", c1.t.getName()); + checkEMFPropertiesAfterCreating(_PU1, c1.emf); + + // create second emf + OnConcurrentEMF c2 = new OnConcurrentEMF(_PU2, "emf2"); + try + { + c2.t.join(); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + Assert.assertEquals("emf2", c2.t.getName()); + checkEMFPropertiesAfterCreating(_PU2, c2.emf); + + // close first emf + c1.close(); + checkEMFPropertyAfterClosing(_PU1, c1.emf); + + // close second emf + c2.close(); + checkEMFPropertyAfterClosing(_PU2, c2.emf); + + } + + /** + * @param _PU1 + */ + private void checkEMFPropertyAfterClosing(String _PU1, EntityManagerFactory emf) + { + Assert.assertFalse(emf.isOpen()); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadata(_PU1)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadataMap().get(_PU1)); +// Assert.assertNull(KunderaMetadata.INSTANCE.getClientMetadata(_PU1)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodelMap().get(_PU1)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(_PU1)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetaModelBuilder(_PU1)); +// Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getSchemaMetadata().getPuToSchemaMetadata() +// .get(_PU1)); + } + + /** + * @param pu + */ + private void checkEMFPropertiesAfterCreating(String pu, EntityManagerFactory emf) + { + Assert.assertTrue(emf.isOpen()); + EntityManager em = emf.createEntityManager(); + Assert.assertNotNull(em); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadata(pu)); + Assert.assertFalse(KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadataMap().isEmpty()); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadataMap().get(pu)); +// Assert.assertNotNull(KunderaMetadata.INSTANCE.getClientMetadata(pu)); + Assert.assertFalse(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodelMap().isEmpty()); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodelMap().get(pu)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(pu)); + Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getMetaModelBuilder(pu)); + // TODO: Devise better way. +// Assert.assertNotNull(KunderaMetadata.INSTANCE.getApplicationMetadata().getSchemaMetadata() +// .getPuToSchemaMetadata().get(pu)); +// Assert.assertNull(KunderaMetadata.INSTANCE.getClientMetadata(pu).getLuceneIndexDir()); + } + + private class OnConcurrentEMF implements Runnable + { + public Thread t; + + private String _PU; + + public EntityManagerFactory emf; + + /** + * @param pu + * @param name + * + */ + + public OnConcurrentEMF(String pu, String name) + { + this._PU = pu; + t = new Thread(this); + t.setName(name); + t.start(); + } + + @Override + public void run() + { + emf = Persistence.createEntityManagerFactory(_PU); + checkEMFPropertiesAfterCreating(_PU, emf); + + } + + public void close() + { + emf.close(); + checkEMFPropertyAfterClosing(_PU, emf); + } + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryCQLV3Test.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryCQLV3Test.java new file mode 100644 index 000000000..81db7ea15 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryCQLV3Test.java @@ -0,0 +1,291 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.persistence; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.ConsistencyLevel; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.cassandra.pelops.PelopsClient; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * + * + * @author amresh.singh + */ +public class NativeQueryCQLV3Test +{ + + private final String schema = "kunderaexamples"; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + // CassandraCli.initClient(); + // CassandraCli.dropKeySpace(schema); + // CassandraCli.createKeySpace(schema); + String nativeSql = "CREATE KEYSPACE " + schema + + " with replication = {'class':'SimpleStrategy', 'replication_factor':1}"; + // strategy_class = 'SimpleStrategy' and + // strategy_options:replication_factor=1" + CassandraCli.executeCqlQuery(nativeSql); + } + + /** + * Test create insert column family query. + */ + @Test + public void testCreateInsertColumnFamilyQueryVersion3() + { + // CassandraCli.dropKeySpace("KunderaExamples"); + + String useNativeSql = "USE " + schema; + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; + + Map clientMap = (Map) em.getDelegate(); + PelopsClient pc = (PelopsClient) clientMap.get("cassandra"); + pc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + // Query q = em.createNativeQuery(nativeSql, + // CassandraEntity.class); + // // q.getResultList(); + // q.executeUpdate(); + Query q = em.createNativeQuery(useNativeSql, CassandraEntity.class); + // q.getResultList(); + q.executeUpdate(); + // create column family + String colFamilySql = "CREATE COLUMNFAMILY users (key varchar PRIMARY KEY,full_name varchar, birth_date int,state varchar)"; + q = em.createNativeQuery(colFamilySql, CassandraEntity.class); + // q.getResultList(); + q.executeUpdate(); + Assert.assertTrue(CassandraCli.columnFamilyExist("users", "test")); + + // Add indexes + String idxSql = "CREATE INDEX ON users (birth_date)"; + q = em.createNativeQuery(idxSql, CassandraEntity.class); + // q.getResultList(); + q.executeUpdate(); + idxSql = "CREATE INDEX ON users (state)"; + q = em.createNativeQuery(idxSql, CassandraEntity.class); + // q.getResultList(); + q.executeUpdate(); + // insert users. + String insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('bsanderson', 'Brandon Sanderson', 1975, 'UT')"; + q = em.createNativeQuery(insertSql, CassandraEntity.class); + // q.getResultList(); + q.executeUpdate(); + // select key and state + String selectSql = "SELECT key, state FROM users"; + + q = em.createNativeQuery(selectSql, CassandraEntity.class); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("bsanderson", results.get(0).getKey()); + Assert.assertEquals("UT", results.get(0).getState()); + Assert.assertNull(results.get(0).getFull_name()); + + // insert users. + insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('prothfuss', 'Patrick Rothfuss', 1973, 'WI')"; + q = em.createNativeQuery(insertSql, CassandraEntity.class); + q.getResultList(); + + insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('htayler', 'Howard Tayler', 1968, 'UT')"; + q = em.createNativeQuery(insertSql, CassandraEntity.class); + q.getResultList(); + + // select all + String selectAll = "SELECT * FROM users WHERE state='UT' AND birth_date > 1970 Allow Filtering"; + q = em.createNativeQuery(selectAll, CassandraEntity.class); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("bsanderson", results.get(0).getKey()); + Assert.assertEquals("UT", results.get(0).getState()); + Assert.assertEquals("Brandon Sanderson", results.get(0).getFull_name()); + Assert.assertEquals(new Integer(1975), results.get(0).getBirth_date()); + emf.close(); + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + String persistenceUnit = "cassandra"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, schema); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("cassandra", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(CassandraEntity.class.getName(), pus); + clazzToPu.put(CassandraBatchEntity.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntity.class); + EntityMetadata m1 = new EntityMetadata(CassandraBatchEntity.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntity.class, m); + processor.process(CassandraBatchEntity.class, m1); + + m.setPersistenceUnit(persistenceUnit); + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntity.class, m); + metaModel.addEntityMetadata(CassandraBatchEntity.class, m1); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + EntityManagerFactoryImpl emf = new EntityManagerFactoryImpl(persistenceUnit, props); + String[] persistenceUnits = new String[] { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + return emf; + } + + @Test + public void testCQLBatch() + { + String useNativeSql = "USE " + schema; + EntityManagerFactory emf = getEntityManagerFactory(); + String createColumnFamily = "CREATE TABLE CassandraBatchEntity ( user_name varchar PRIMARY KEY, password varchar, name varchar)"; + String batchOps = "BEGIN BATCH INSERT INTO CassandraBatchEntity (user_name, password, name) VALUES ('user2', 'ch@ngem3b', 'second user') UPDATE CassandraBatchEntity SET password = 'ps22dhds' WHERE user_name = 'user2' INSERT INTO CassandraBatchEntity (user_name, password) VALUES ('user3', 'ch@ngem3c') DELETE name FROM CassandraBatchEntity WHERE user_name = 'user2' INSERT INTO CassandraBatchEntity (user_name, password, name) VALUES ('user4', 'ch@ngem3c', 'Andrew') APPLY BATCH"; + + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; + + Map clientMap = (Map) em.getDelegate(); + PelopsClient pc = (PelopsClient) clientMap.get("cassandra"); + pc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + + Query q = em.createNativeQuery(useNativeSql, CassandraBatchEntity.class); + // q.getResultList(); + q.executeUpdate(); + + pc.setConsistencyLevel(ConsistencyLevel.QUORUM); + q = em.createNativeQuery(createColumnFamily, CassandraBatchEntity.class); + // q.getResultList(); + q.executeUpdate(); + + pc.setConsistencyLevel(ConsistencyLevel.QUORUM); + q = em.createNativeQuery(batchOps, CassandraBatchEntity.class); + // q.getResultList(); + q.executeUpdate(); + + q = em.createNativeQuery("select * from CassandraBatchEntity", CassandraBatchEntity.class); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + // Multiple table batch processing. + + createColumnFamily = "create table test1 (id timeuuid primary key, url text, userid uuid, datetime timestamp, linkcounts int)"; + em.createNativeQuery(createColumnFamily, CassandraBatchEntity.class).executeUpdate(); + createColumnFamily = "create table test2 (key text primary key, count int)"; + em.createNativeQuery(createColumnFamily, CassandraBatchEntity.class).executeUpdate(); + batchOps = "BEGIN BATCH INSERT INTO test1(id, url) VALUES (64907b40-29a1-11e2-93fa-90b11c71b811,'w') INSERT INTO test2(key, count) VALUES ('key1',12) APPLY BATCH"; + em.createNativeQuery(batchOps, CassandraBatchEntity.class).executeUpdate(); + emf.close(); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + // CassandraCli.dropKeySpace("KunderaExamples"); + CassandraCli.dropKeySpace(schema); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryTest.java new file mode 100644 index 000000000..60b9e1694 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NativeQueryTest.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.persistence; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.scale7.cassandra.pelops.pool.IThriftPool.IPooledConnection; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; +import com.impetus.kundera.query.QueryImpl; + +/** + * Junit test case for NativeQuery support. + * + * @author vivek.mishra + * + */ +public class NativeQueryTest +{ + // /** The schema. */ + private final String schema = "KunderaExamples"; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(schema); + } + + /** + * Test create native query. + */ + @Test + public void testCreateNativeQuery() + { + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; + String nativeSql = "Select * from Cassandra c"; + + QueryImpl q = (QueryImpl) em.createNativeQuery(nativeSql, CassandraEntitySample.class); + Assert.assertEquals(nativeSql, q.getJPAQuery()); + Assert.assertEquals(true, KunderaMetadata.INSTANCE.getApplicationMetadata().isNative(nativeSql)); + } + + /** + * Test execute native create keyspace query. + */ + @Test + public void testExecutNativeQuery() + { + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + // String nativeSql = "CREATE KEYSPACE " + schema + // + + // " with strategy_class = 'SimpleStrategy' and strategy_options:replication_factor=1"; + String useNativeSql = "USE " + "KunderaExamples"; + + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; +// Map clientMap = (Map) em.getDelegate(); +// PelopsClient pc = (PelopsClient) clientMap.get("cassandra"); +// pc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + // Query q = em.createNativeQuery(nativeSql, + // CassandraEntitySample.class); + // // q.getResultList(); + // q.executeUpdate(); + Query q = em.createNativeQuery(useNativeSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + Assert.assertTrue(CassandraCli.keyspaceExist(schema)); + Assert.assertFalse(CassandraCli.keyspaceExist("invalidSchema")); + } + + /** + * Native queries should not leak connections. Pelops pool fails providing a + * connection if we don't call {@link IPooledConnection#release()} + */ + @Test + public void testReleasesNativeQueryConnection() + { + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + // String nativeSql = "CREATE KEYSPACE " + // + schema + // + + // " with strategy_class = 'SimpleStrategy' and strategy_options:replication_factor=1"; + // String useNativeSql = "USE test"; + String useNativeSql = "USE " + "KunderaExamples"; + + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; +// Map clientMap = (Map) em.getDelegate(); +// PelopsClient pc = (PelopsClient) clientMap.get("cassandra"); +// pc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + // Query q = em.createNativeQuery(nativeSql, + // CassandraEntitySample.class); + // // q.getResultList(); + // q.executeUpdate(); + + // won't be able to loop if connections are leaked + for (int i = 0; i < 30; i++) + { + Query q = em.createNativeQuery(useNativeSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + } + } + + /** + * Test create insert column family query. + */ + @Test + public void testCreateInsertColumnFamilyQuery() + { + // String nativeSql = "CREATE KEYSPACE " + schema + // + + // " with strategy_class = 'SimpleStrategy' and strategy_options:replication_factor=1"; + // String useNativeSql = "USE test"; + String useNativeSql = "USE " + "KunderaExamples"; + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + EntityManager em = emf.createEntityManager()/* + * new + * EntityManagerImpl(emf, + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL, + * PersistenceContextType + * .EXTENDED) + */; +// Map clientMap = (Map) em.getDelegate(); +// PelopsClient pc = (PelopsClient) clientMap.get("cassandra"); +// pc.setCqlVersion(CassandraConstants.CQL_VERSION_3_0); + // Query q = em.createNativeQuery(nativeSql, + // CassandraEntitySample.class); + // // q.getResultList(); + // q.executeUpdate(); + Query q = em.createNativeQuery(useNativeSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + // create column family + String colFamilySql = "CREATE COLUMNFAMILY users (key varchar PRIMARY KEY,full_name varchar, birth_date int,state varchar)"; + q = em.createNativeQuery(colFamilySql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + Assert.assertTrue(CassandraCli.columnFamilyExist("users", "test")); + + // Add indexes + String idxSql = "CREATE INDEX ON users (birth_date)"; + q = em.createNativeQuery(idxSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + idxSql = "CREATE INDEX ON users (state)"; + q = em.createNativeQuery(idxSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + // insert users. + String insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('bsanderson', 'Brandon Sanderson', 1975, 'UT')"; + q = em.createNativeQuery(insertSql, CassandraEntitySample.class); + // q.getResultList(); + q.executeUpdate(); + // select key and state + String selectSql = "SELECT key, state FROM users"; + + q = em.createNativeQuery(selectSql, CassandraEntitySample.class); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("bsanderson", results.get(0).getKey()); + Assert.assertEquals("UT", results.get(0).getState()); + Assert.assertNull(results.get(0).getFull_name()); + + // insert users. + insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('prothfuss', 'Patrick Rothfuss', 1973, 'WI')"; + q = em.createNativeQuery(insertSql, CassandraEntitySample.class); + q.getResultList(); + + insertSql = "INSERT INTO users (key, full_name, birth_date, state) VALUES ('htayler', 'Howard Tayler', 1968, 'UT')"; + q = em.createNativeQuery(insertSql, CassandraEntitySample.class); + q.getResultList(); + + // select all + String selectAll = "SELECT * FROM users WHERE state='UT' AND birth_date > 1970"; + q = em.createNativeQuery(selectAll, CassandraEntitySample.class); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("bsanderson", results.get(0).getKey()); + Assert.assertEquals("UT", results.get(0).getState()); + Assert.assertEquals("Brandon Sanderson", results.get(0).getFull_name()); + Assert.assertEquals(new Integer(1975), results.get(0).getBirth_date()); + + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + String persistenceUnit = "cassandra"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaExamples"); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("cassandra", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(CassandraEntitySample.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntitySample.class); + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntitySample.class, m); + m.setPersistenceUnit(persistenceUnit); + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntitySample.class, m); + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + EntityManagerFactoryImpl emf = new EntityManagerFactoryImpl(persistenceUnit, props); + String[] persistenceUnits = new String[] { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + return emf; + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + // CassandraCli.dropKeySpace("KunderaExamples"); + CassandraCli.dropKeySpace(schema); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NullableFieldAccessorTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NullableFieldAccessorTest.java new file mode 100644 index 000000000..7b7b7251e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/NullableFieldAccessorTest.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.persistence; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.persistence.EntityManager; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * @author kuldeep.mishra + * + * The Class PersistWithNullField. + */ +public class NullableFieldAccessorTest +{ + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("KunderaExamples"); + Cassandra.Client client = CassandraCli.getClient(); + client.set_keyspace("KunderaExamples"); + CfDef cf_def = new CfDef(); + cf_def.keyspace = "KunderaExamples"; + cf_def.name = "users"; + cf_def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("full_name".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + cf_def.addToColumn_metadata(columnDef2); + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("birth_date".getBytes()), "Int32Type"); + columnDef3.index_type = IndexType.KEYS; + cf_def.addToColumn_metadata(columnDef3); + ColumnDef columnDef4 = new ColumnDef(ByteBuffer.wrap("state".getBytes()), "UTF8Type"); + columnDef4.index_type = IndexType.KEYS; + cf_def.addToColumn_metadata(columnDef4); + client.system_add_column_family(cf_def); + } + + /** + * Test. + */ + @Test + public void test() + { + EntityManagerFactoryImpl emf = getEntityManagerFactory(); + EntityManager em = emf.createEntityManager(); + CassandraEntitySample entity = new CassandraEntitySample(); + entity.setKey("123"); + entity.setFull_name("kuldeep mishra"); + entity.setState("delhi"); + // birth_date is null + + em.persist(entity); + + CassandraEntitySample findEntity = em.find(CassandraEntitySample.class, 123); + Assert.assertNotNull(findEntity); + Assert.assertEquals("123", findEntity.getKey()); + Assert.assertEquals("kuldeep mishra", findEntity.getFull_name()); + Assert.assertEquals("delhi", findEntity.getState()); + Assert.assertNull(findEntity.getBirth_date()); + + emf.close(); + + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + String persistenceUnit = "cassandra"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaExamples"); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("cassandra", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(CassandraEntitySample.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntitySample.class); + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntitySample.class, m); + m.setPersistenceUnit(persistenceUnit); + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntitySample.class, m); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + new ClientFactoryConfiguraton(null, persistenceUnit).configure(); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + EntityManagerFactoryImpl emf = new EntityManagerFactoryImpl(persistenceUnit, props); + return emf; + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("KunderaExamples"); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/UpdateDeleteNamedQueryTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/UpdateDeleteNamedQueryTest.java new file mode 100644 index 000000000..7cae2b3a6 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/persistence/UpdateDeleteNamedQueryTest.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.persistence; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * Test case for update/delete via JPQL. + * + * @author vivek.mishra + * + */ +public class UpdateDeleteNamedQueryTest +{ + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + // CassandraCli.createKeySpace("KunderaExamples"); + + loadData(); + } + + /** + * @throws TException + * @throws InvalidRequestException + * @throws SchemaDisagreementException + * + */ + private void loadData() throws InvalidRequestException, TException, SchemaDisagreementException + { + KsDef ksDef = null; + CfDef user_Def = new CfDef(); + user_Def.name = "users"; + user_Def.keyspace = "KunderaExamples"; + user_Def.setComparator_type("UTF8Type"); + user_Def.setDefault_validation_class("UTF8Type"); + user_Def.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("birth_date".getBytes()), "Int32Type"); + columnDef.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("state".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef1); + + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("full_name".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + user_Def.addToColumn_metadata(columnDef2); + + List cfDefs = new ArrayList(); + cfDefs.add(user_Def); + + ksDef = new KsDef("KunderaExamples", "org.apache.cassandra.locator.SimpleStrategy", cfDefs); + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + CassandraCli.client.system_add_keyspace(ksDef); + } + + @Test + public void testUpdate() + { + EntityManagerFactory emf = getEntityManagerFactory(); + EntityManager em = emf.createEntityManager(); + + // String colFamilySql = + // "CREATE COLUMNFAMILY users (key varchar PRIMARY KEY,full_name varchar, birth_date int,state varchar)"; + // Query q1 = em.createNativeQuery(colFamilySql, + // CassandraEntitySample.class); + // q1.executeUpdate(); + // + // String idxSql = "CREATE INDEX ON users (birthDate)"; + // q1 = em.createNativeQuery(idxSql, CassandraEntitySample.class); + // q1.executeUpdate(); + // + // idxSql = "CREATE INDEX ON users (state)"; + // q1 = em.createNativeQuery(idxSql, CassandraEntitySample.class); + // q1.executeUpdate(); + + CassandraEntitySample entity = new CassandraEntitySample(); + entity.setBirth_date(new Integer(100112)); + entity.setFull_name("impetus_emp"); + entity.setKey("k"); + entity.setState("UP"); + em.persist(entity); + + String updateQuery = "Update CassandraEntitySample c SET c.state = DELHI where c.state = UP"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + + CassandraEntitySample result = em.find(CassandraEntitySample.class, "k"); + Assert.assertNotNull(result); + // Assert.assertEquals("DELHI", result.getState()); // This should be + // uncommented later. as merge got some issue. + String deleteQuery = "Delete From CassandraEntitySample c where c.state=UP"; + + q = em.createQuery(deleteQuery); + // q = em.createNamedQuery("delete.query"); + q.executeUpdate(); + result = em.find(CassandraEntitySample.class, "k"); + // Assert.assertNull(result); // This should be uncommented later. as + // merge got some issue. + emf.close(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("KunderaExamples"); + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + String persistenceUnit = "cassandra"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.thrift.ThriftClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaExamples"); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("cassandra", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(CassandraEntitySample.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntitySample.class); + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntitySample.class, m); + m.setPersistenceUnit(persistenceUnit); + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntitySample.class, m); + metaModel.addEntityNameToClassMapping("CassandraEntitySample", CassandraEntitySample.class); + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + + CassandraPropertyReader reader = new CassandraPropertyReader(null); + reader.read(persistenceUnit); + String[] persistenceUnits = new String[] { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + EntityManagerFactoryImpl emf = new EntityManagerFactoryImpl(persistenceUnit, props); + return emf; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraPropertiesTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraPropertiesTest.java new file mode 100644 index 000000000..b0e1a0376 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraPropertiesTest.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.schemamanager.entites.Doctor; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep.Mishra + * + */ +public class CassandraPropertiesTest +{ + private static final String HOME_IMPADMIN_LUCENE = "/home/impadmin/lucene"; + + private static final String KUNDERA_CASSANDRA_PROPERTIES = "kundera-cassandra.properties"; + + /** The configuration. */ + private SchemaConfiguration configuration; + + /** + * cassandra client + */ + private Cassandra.Client client; + + /** + * keyspace to create. + */ + private String keyspace = "KunderaExamplesTests1"; + + /** + * persistence unit pu. + */ + private String pu = "secIdxCassandra"; + + /** + * useLucene + */ + private final boolean useLucene = true; + + private Logger log = LoggerFactory.getLogger(CassandraPropertiesTest.class); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + client = CassandraCli.getClient(); + configuration = new SchemaConfiguration(null, pu); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(keyspace); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } + + @Test + public void testValid() throws NotFoundException, InvalidRequestException, TException, IOException + {/* + * try { getEntityManagerFactory("create"); + * + * PersistenceUnitMetadata puMetadata = + * KunderaMetadataManager.getPersistenceUnitMetadata(pu); Properties + * properties = new Properties(); InputStream inStream = puMetadata != null + * ? ClassLoader.getSystemResourceAsStream(puMetadata + * .getProperty(PersistenceProperties.KUNDERA_CLIENT_PROPERTY)) : null; + * properties.load(inStream); String expected_replication = + * properties.getProperty(CassandraConstants.REPLICATION_FACTOR); String + * expected_strategyClass = + * properties.getProperty(CassandraConstants.PLACEMENT_STRATEGY); + * + * KsDef ksDef = client.describe_keyspace(keyspace); + * Assert.assertEquals(expected_replication, + * ksDef.strategy_options.get("replication_factor")); + * Assert.assertEquals(expected_strategyClass, ksDef.getStrategy_class()); + * } catch (IOException e) { + * log.warn("kundera-cassandra.properties file not found"); } + */ + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + ClientMetadata clientMetadata = new ClientMetadata(); + Map props = new HashMap(); + // String pu = pu; + props.put(Constants.PERSISTENCE_UNIT_NAME, pu); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, PelopsClientFactory.class.getName()); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, keyspace); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + + props.put(PersistenceProperties.KUNDERA_CLIENT_PROPERTY, KUNDERA_CASSANDRA_PROPERTIES); + + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, HOME_IMPADMIN_LUCENE); + + clientMetadata.setLuceneIndexDir(HOME_IMPADMIN_LUCENE); + } + else + { + + clientMetadata.setLuceneIndexDir(null); + } + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(pu); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(pu, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(pu); + clazzToPu.put(Doctor.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(Doctor.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(Doctor.class, m); + + m.setPersistenceUnit(pu); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(Doctor.class, m); + + appMetadata.getMetamodelMap().put(pu, metaModel); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(pu).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(pu).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(pu).getMappedSuperClassTypes()); + +// KunderaMetadata.INSTANCE.addClientMetadata(pu, clientMetadata); + // CassandraPropertyReader reader = new CassandraPropertyReader(); + try + { + configuration.configure(); + } + catch (Exception e) + { + log.info("kundera-cassandra.properties file not found."); + + } + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTM.java new file mode 100644 index 000000000..fb24899dc --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTM.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.schemamanager.entites.CassandraEntityHabitatUniMToM; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonnelUniMToM; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep.Kumar + * + */ +public class CassandraSchemaManagerMTM +{ + private static final String keyspace = "KunderaCassandraExamples"; + + private static final String pu = "cassandra"; + + private final boolean useLucene = false; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(keyspace); + } + + @Test + public void test() + { + try + { + getEntityManagerFactory("create"); + + Assert.assertTrue(CassandraCli.keyspaceExist(keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonnelUniMToM", keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityHabitatUniMToM", keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("PERSONNEL_ADDRESS", keyspace)); + } + catch (InvalidEntityDefinitionException iedex) + { + Assert.assertEquals("It's manadatory to use @JoinTable with parent side of ManyToMany relationship.", + iedex.getMessage()); + } + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + Map props = new HashMap(); + props.put(Constants.PERSISTENCE_UNIT_NAME, pu); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, keyspace); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "/home/impadmin/lucene"); + } + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(pu); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(pu, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(pu); + clazzToPu.put(CassandraEntityPersonnelUniMToM.class.getName(), pus); + clazzToPu.put(CassandraEntityHabitatUniMToM.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntityPersonnelUniMToM.class); + EntityMetadata m1 = new EntityMetadata(CassandraEntityHabitatUniMToM.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntityPersonnelUniMToM.class, m); + processor.process(CassandraEntityHabitatUniMToM.class, m1); + + m.setPersistenceUnit(pu); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntityPersonnelUniMToM.class, m); + metaModel.addEntityMetadata(CassandraEntityHabitatUniMToM.class, m1); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(pu).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(pu).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(pu).getMappedSuperClassTypes()); + + appMetadata.getMetamodelMap().put(pu, metaModel); + + new ClientFactoryConfiguraton(null, pu).configure(); + new SchemaConfiguration(null, pu).configure(); + // EntityManagerFactoryImpl impl = new + // EntityManagerFactoryImpl(puMetadata, props); + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTMTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTMTest.java new file mode 100644 index 000000000..974e98e0b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerMTMTest.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.schemamanager.entites.CassandraEntityHabitatUniMToM; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonnelUniMToM; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep.Kumar + * + */ +public class CassandraSchemaManagerMTMTest +{ + private static final String _keyspace = "KunderaCassandraMTMExamples"; + + private static final String _persistenceUnit = "cassandra"; + + /** The configuration. */ + private SchemaConfiguration configuration; + + private final boolean useLucene = false; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + configuration = new SchemaConfiguration(null, _persistenceUnit); + CassandraCli.cassandraSetUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(_keyspace); + } + + @Test + public void test() + { + try + { + getEntityManagerFactory("create"); + Assert.assertTrue(CassandraCli.keyspaceExist(_keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonnelUniMToM", _keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityHabitatUniMToM", _keyspace)); + Assert.assertTrue(CassandraCli.columnFamilyExist("PERSONNEL_ADDRESS", _keyspace)); + } + catch (InvalidEntityDefinitionException iedex) + { + Assert.assertEquals("It's manadatory to use @JoinTable with parent side of ManyToMany relationship.", + iedex.getMessage()); + } + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + Map props = new HashMap(); + props.put(Constants.PERSISTENCE_UNIT_NAME, _persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, PelopsClientFactory.class.getName()); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, _keyspace); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "/home/impadmin/lucene"); + } + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(_persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(_persistenceUnit, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(_persistenceUnit); + clazzToPu.put(CassandraEntityPersonnelUniMToM.class.getName(), pus); + clazzToPu.put(CassandraEntityHabitatUniMToM.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntityPersonnelUniMToM.class); + EntityMetadata m1 = new EntityMetadata(CassandraEntityHabitatUniMToM.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntityPersonnelUniMToM.class, m); + processor.process(CassandraEntityHabitatUniMToM.class, m1); + + m.setPersistenceUnit(_persistenceUnit); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntityPersonnelUniMToM.class, m); + metaModel.addEntityMetadata(CassandraEntityHabitatUniMToM.class, m1); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(_persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(_persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(_persistenceUnit).getMappedSuperClassTypes()); + + appMetadata.getMetamodelMap().put(_persistenceUnit, metaModel); + + new ClientFactoryConfiguraton(null, _persistenceUnit).configure(); + configuration.configure(); + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerTest.java new file mode 100644 index 000000000..e3026cbf1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerTest.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.schemamanager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.schemamanager.entites.CassandraEmbeddedPersonUniMto1; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressBi1To1FK; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressBi1To1PK; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressBi1ToM; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressBiMTo1; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressUni1To1; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressUni1To1PK; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressUni1ToM; +import com.impetus.client.schemamanager.entites.CassandraEntityAddressUniMTo1; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonBi1To1FK; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonBi1To1PK; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonBi1ToM; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonBiMTo1; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonUni1To1; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonUni1To1PK; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonUni1ToM; +import com.impetus.client.schemamanager.entites.CassandraEntityPersonUniMto1; +import com.impetus.client.schemamanager.entites.CassandraEntitySuper; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.IndexProcessor; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * CassandraSchemaManagerTest class test the auto creation schema property in + * cassandra data store. + * + * @author Kuldeep.Kumar + * + */ +public class CassandraSchemaManagerTest +{ + private static final String _PU = "CassandraSchemaManager"; + + private static final String _KEYSPACE = "CassandraSchemaManagerTest"; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace(_KEYSPACE); + } + + /** + * Test schema operation. + * + * @throws IOException + * Signals that an I/O exception has occurred. + * @throws TException + * the t exception + * @throws InvalidRequestException + * the invalid request exception + * @throws UnavailableException + * the unavailable exception + * @throws TimedOutException + * the timed out exception + * @throws SchemaDisagreementException + * the schema disagreement exception + */ + @Test + public void schemaOperation() throws IOException, TException, InvalidRequestException, UnavailableException, + TimedOutException, SchemaDisagreementException + { + getEntityManagerFactory(); + Assert.assertTrue(CassandraCli.keyspaceExist(_KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySuper", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressUni1To1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressUniMTo1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressUni1ToM", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonUniMto1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonUni1ToM", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonUni1To1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonUni1To1PK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressUni1To1PK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonBi1To1FK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonBi1To1PK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonBi1ToM", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityPersonBiMTo1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressBi1To1FK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressBi1To1PK", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressBi1ToM", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntityAddressBiMTo1", _KEYSPACE)); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEmbeddedPersonUniMto1", _KEYSPACE)); + + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + props.put(Constants.PERSISTENCE_UNIT_NAME, _PU); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, _KEYSPACE); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(_PU); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(_PU, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(_PU); + clazzToPu.put(CassandraEntitySuper.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressUni1To1.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressUni1ToM.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressUniMTo1.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonUniMto1.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonUni1To1.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonUni1ToM.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressUni1To1PK.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonUni1To1PK.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonBi1To1FK.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonBi1To1PK.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonBi1ToM.class.getName(), pus); + clazzToPu.put(CassandraEntityPersonBiMTo1.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressBi1To1FK.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressBi1To1PK.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressBi1ToM.class.getName(), pus); + clazzToPu.put(CassandraEntityAddressBiMTo1.class.getName(), pus); + clazzToPu.put(CassandraEmbeddedPersonUniMto1.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m1 = new EntityMetadata(CassandraEntitySuper.class); + EntityMetadata m2 = new EntityMetadata(CassandraEntityAddressUni1To1.class); + EntityMetadata m3 = new EntityMetadata(CassandraEntityAddressUni1ToM.class); + EntityMetadata m4 = new EntityMetadata(CassandraEntityAddressUniMTo1.class); + EntityMetadata m5 = new EntityMetadata(CassandraEntityPersonUniMto1.class); + EntityMetadata m6 = new EntityMetadata(CassandraEntityPersonUni1To1.class); + EntityMetadata m7 = new EntityMetadata(CassandraEntityPersonUni1ToM.class); + EntityMetadata m8 = new EntityMetadata(CassandraEntityPersonUni1To1PK.class); + EntityMetadata m9 = new EntityMetadata(CassandraEntityAddressUni1To1PK.class); + EntityMetadata m10 = new EntityMetadata(CassandraEntityAddressBi1To1FK.class); + EntityMetadata m11 = new EntityMetadata(CassandraEntityAddressBi1To1PK.class); + EntityMetadata m12 = new EntityMetadata(CassandraEntityAddressBi1ToM.class); + EntityMetadata m13 = new EntityMetadata(CassandraEntityAddressBiMTo1.class); + EntityMetadata m14 = new EntityMetadata(CassandraEntityPersonBi1To1FK.class); + EntityMetadata m15 = new EntityMetadata(CassandraEntityPersonBi1To1PK.class); + EntityMetadata m16 = new EntityMetadata(CassandraEntityPersonBi1ToM.class); + EntityMetadata m17 = new EntityMetadata(CassandraEntityPersonBiMTo1.class); + EntityMetadata m18 = new EntityMetadata(CassandraEmbeddedPersonUniMto1.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntitySuper.class, m1); + processor.process(CassandraEntityAddressUni1To1.class, m2); + processor.process(CassandraEntityAddressUni1ToM.class, m3); + processor.process(CassandraEntityAddressUniMTo1.class, m4); + processor.process(CassandraEntityPersonUniMto1.class, m5); + processor.process(CassandraEntityPersonUni1To1.class, m6); + processor.process(CassandraEntityPersonUni1ToM.class, m7); + processor.process(CassandraEntityPersonUni1To1PK.class, m8); + processor.process(CassandraEntityAddressUni1To1PK.class, m9); + processor.process(CassandraEntityAddressBi1To1FK.class, m10); + processor.process(CassandraEntityAddressBi1To1PK.class, m11); + processor.process(CassandraEntityAddressBi1ToM.class, m12); + processor.process(CassandraEntityAddressBiMTo1.class, m13); + processor.process(CassandraEntityPersonBi1To1FK.class, m14); + processor.process(CassandraEntityPersonBi1To1PK.class, m15); + processor.process(CassandraEntityPersonBi1ToM.class, m16); + processor.process(CassandraEntityPersonBiMTo1.class, m17); + processor.process(CassandraEmbeddedPersonUniMto1.class, m18); + + IndexProcessor indexProcessor = new IndexProcessor(); + indexProcessor.process(CassandraEntityPersonUniMto1.class, m5); + + m1.setPersistenceUnit(_PU); + m2.setPersistenceUnit(_PU); + m3.setPersistenceUnit(_PU); + m4.setPersistenceUnit(_PU); + m5.setPersistenceUnit(_PU); + m6.setPersistenceUnit(_PU); + m7.setPersistenceUnit(_PU); + m8.setPersistenceUnit(_PU); + m9.setPersistenceUnit(_PU); + m10.setPersistenceUnit(_PU); + m11.setPersistenceUnit(_PU); + m12.setPersistenceUnit(_PU); + m13.setPersistenceUnit(_PU); + m14.setPersistenceUnit(_PU); + m15.setPersistenceUnit(_PU); + m16.setPersistenceUnit(_PU); + m17.setPersistenceUnit(_PU); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntitySuper.class, m1); + metaModel.addEntityMetadata(CassandraEntityAddressUni1To1.class, m2); + metaModel.addEntityMetadata(CassandraEntityAddressUni1ToM.class, m3); + metaModel.addEntityMetadata(CassandraEntityAddressUniMTo1.class, m4); + metaModel.addEntityMetadata(CassandraEntityPersonUniMto1.class, m5); + metaModel.addEntityMetadata(CassandraEntityPersonUni1To1.class, m6); + metaModel.addEntityMetadata(CassandraEntityPersonUni1ToM.class, m7); + metaModel.addEntityMetadata(CassandraEntityPersonUni1To1PK.class, m8); + metaModel.addEntityMetadata(CassandraEntityAddressUni1To1PK.class, m9); + metaModel.addEntityMetadata(CassandraEntityAddressBi1To1FK.class, m10); + metaModel.addEntityMetadata(CassandraEntityAddressBi1To1PK.class, m11); + metaModel.addEntityMetadata(CassandraEntityAddressBi1ToM.class, m12); + metaModel.addEntityMetadata(CassandraEntityAddressBiMTo1.class, m13); + metaModel.addEntityMetadata(CassandraEntityPersonBi1To1FK.class, m14); + metaModel.addEntityMetadata(CassandraEntityPersonBi1To1PK.class, m15); + metaModel.addEntityMetadata(CassandraEntityPersonBi1ToM.class, m16); + metaModel.addEntityMetadata(CassandraEntityPersonBiMTo1.class, m17); + metaModel.addEntityMetadata(CassandraEmbeddedPersonUniMto1.class, m18); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(_PU).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(_PU).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(_PU).getMappedSuperClassTypes()); + + appMetadata.getMetamodelMap().put(_PU, metaModel); + + new ClientFactoryConfiguraton(null, _PU).configure(); + new SchemaConfiguration(null, _PU).configure(); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + // EntityManagerFactoryImpl impl = new + // EntityManagerFactoryImpl(puMetadata, props); + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerValidateEntityTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerValidateEntityTest.java new file mode 100644 index 000000000..c25cb09f1 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaManagerValidateEntityTest.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.config.CassandraPropertyReader; +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.cassandra.schemamanager.CassandraSchemaManager; +import com.impetus.client.schemamanager.entites.InvalidCounterColumnEntity; +import com.impetus.client.schemamanager.entites.ValidCounterColumnFamily; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * @author impadmin + * + */ +public class CassandraSchemaManagerValidateEntityTest +{ + + private String persistenceUnit = "cassandraProperties"; + + // private String[] persistenceUnits = new String[] {persistenceUnit}; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + /** + * Test method for + * {@link com.impetus.client.cassandra.schemamanager.CassandraSchemaManager#validateEntity(java.lang.Class)} + * . + */ + @Test + public void testValidateEntity() + { + getEntityManagerFactory(); + CassandraPropertyReader reader = new CassandraPropertyReader(null); + reader.read(persistenceUnit); + CassandraSchemaManager manager = new CassandraSchemaManager(PelopsClientFactory.class.getName(), null); + boolean valid = manager.validateEntity(ValidCounterColumnFamily.class); + Assert.assertTrue(valid); + valid = manager.validateEntity(InvalidCounterColumnEntity.class); + Assert.assertFalse(valid); + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory() + { + Map props = new HashMap(); + // String persistenceUnit = "cassandraProperties"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, + "com.impetus.client.cassandra.pelops.PelopsClientFactory"); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaCounterColumn"); + props.put(PersistenceProperties.KUNDERA_CLIENT_PROPERTY, "kunderaTest.xml"); + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(persistenceUnit, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(ValidCounterColumnFamily.class.getName(), pus); + clazzToPu.put(InvalidCounterColumnEntity.class.getName(), pus); + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(ValidCounterColumnFamily.class); + EntityMetadata m1 = new EntityMetadata(InvalidCounterColumnEntity.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(ValidCounterColumnFamily.class, m); + processor.process(InvalidCounterColumnEntity.class, m1); + m.setPersistenceUnit(persistenceUnit); + m1.setPersistenceUnit(persistenceUnit); + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(ValidCounterColumnFamily.class, m); + metaModel.addEntityMetadata(InvalidCounterColumnEntity.class, m1); + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + + // EntityManagerFactoryImpl emf = new + // EntityManagerFactoryImpl(persistenceUnit, props); + // return emf; + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaOperationTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaOperationTest.java new file mode 100644 index 000000000..1c0dc9199 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassandraSchemaOperationTest.java @@ -0,0 +1,536 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.apache.cassandra.db.marshal.IntegerType; +import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.schemamanager.entites.CassandraEntitySimple; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.IndexProcessor; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep.Kumar + * + */ +public class CassandraSchemaOperationTest +{ + /** The configuration. */ + private SchemaConfiguration configuration; + + /** Configure schema manager. */ + private SchemaManager schemaManager; + + private Cassandra.Client client; + + private final boolean useLucene = false; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + configuration = new SchemaConfiguration(null, "CassandraSchemaOperationTest"); + CassandraCli.cassandraSetUp(); + CassandraCli cli = new CassandraCli(); + client = cli.getClient(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("KunderaCoreExmples"); + } + + @Test + public void testCreate() throws NotFoundException, InvalidRequestException, TException, + UnsupportedEncodingException + { + getEntityManagerFactory("create"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = new KsDef(); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + Assert.assertEquals(1, ksDef.getCf_defs().size()); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.column_type); + Assert.assertEquals(2, cfDef.getColumn_metadata().size()); + List columns = new ArrayList(); + columns.add("AGE"); + columns.add("PERSON_NAME"); + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (new String(columnDef.getName(), Constants.ENCODING).equals("AGE")) + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertEquals(IndexType.KEYS, columnDef.index_type); + } + else + { + + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertEquals(IndexType.KEYS, columnDef.index_type); + } + } + } + } + + @Test + public void testCreatedrop() throws NotFoundException, InvalidRequestException, TException, + UnsupportedEncodingException + { + getEntityManagerFactory("create-drop"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = new KsDef(); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.column_type); + Assert.assertEquals(2, cfDef.getColumn_metadata().size()); + + List columns = new ArrayList(); + columns.add("AGE"); + columns.add("PERSON_NAME"); + + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (new String(columnDef.getName(), Constants.ENCODING).equals("AGE")) + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertEquals(IndexType.KEYS, columnDef.index_type); + } + else + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertEquals(IndexType.KEYS, columnDef.index_type); + } + } + } + + PelopsClientFactory clientFactory = (PelopsClientFactory) ClientResolver + .getClientFactory("CassandraSchemaOperationTest"); + clientFactory.getSchemaManager(null).dropSchema(); + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertFalse(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + } + + @Test + public void testUpdate() throws NotFoundException, InvalidRequestException, TException, + SchemaDisagreementException, UnsupportedEncodingException + { + CassandraCli.createKeySpace("KunderaCoreExmples"); + client.set_keyspace("KunderaCoreExmples"); + org.apache.cassandra.thrift.CfDef cf_def = new org.apache.cassandra.thrift.CfDef("KunderaCoreExmples", + "CassandraEntitySimple"); + cf_def.column_type = "Standard"; + client.system_add_column_family(cf_def); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = new KsDef(); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + // Assert.assertEquals(1, ksDef.getCf_defs().size()); + Assert.assertEquals(0, ksDef.getCf_defs().get(0).getColumn_metadata().size()); + + getEntityManagerFactory("update"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.getColumn_type()); + + int counter = 0; + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (new String(columnDef.getName(), Constants.ENCODING).equals("AGE")) + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertNotNull(columnDef.index_name); + Assert.assertEquals(IntegerType.class.getName(), columnDef.getValidation_class()); + counter++; + } + else + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertEquals("PERSON_NAME", new String(columnDef.getName(), Constants.ENCODING)); + Assert.assertNotNull(columnDef.index_name); + Assert.assertEquals(UTF8Type.class.getName(), columnDef.getValidation_class()); + counter++; + } + } + Assert.assertEquals(2, counter); + } + } + + @Test + public void testUpdateInValid() throws NotFoundException, InvalidRequestException, TException, + SchemaDisagreementException, UnsupportedEncodingException + { + CassandraCli.createKeySpace("KunderaCoreExmples"); + client.set_keyspace("KunderaCoreExmples"); + org.apache.cassandra.thrift.CfDef cf_def = new org.apache.cassandra.thrift.CfDef("KunderaCoreExmples", + "CassandraEntitySimple"); + cf_def.column_type = "Standard"; + List column_metadata = new ArrayList(); + ColumnDef def = new ColumnDef(); + def.setName("AGE".getBytes()); + def.setValidation_class("UTF8Type"); + def.setIndex_type(IndexType.KEYS); + + ColumnDef def1 = new ColumnDef(); + def1.setName("PERSON_NAME".getBytes()); + def1.setValidation_class("UTF8Type"); + def1.setIndex_type(IndexType.KEYS); + + column_metadata.add(def1); + column_metadata.add(def); + + cf_def.setColumn_metadata(column_metadata); + client.system_add_column_family(cf_def); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = client.describe_keyspace("KunderaCoreExmples"); + Assert.assertEquals(1, ksDef.getCf_defs().size()); + Assert.assertEquals(2, ksDef.getCf_defs().get(0).getColumn_metadata().size()); + + getEntityManagerFactory("update"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.getColumn_type()); + + int counter = 0; + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + if (new String(columnDef.getName(), Constants.ENCODING).equals("AGE")) + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertNotNull(columnDef.index_name); + Assert.assertEquals(IntegerType.class.getName(), columnDef.getValidation_class()); + counter++; + } + else + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertEquals("PERSON_NAME", new String(columnDef.getName(), Constants.ENCODING)); + Assert.assertNotNull(columnDef.index_name); + Assert.assertEquals(UTF8Type.class.getName(), columnDef.getValidation_class()); + counter++; + } + } + Assert.assertEquals(2, counter); + } + } + + @Test + public void testValidate() + { + try + { + CassandraCli.createKeySpace("KunderaCoreExmples"); + + client.set_keyspace("KunderaCoreExmples"); + + org.apache.cassandra.thrift.CfDef cf_def = new org.apache.cassandra.thrift.CfDef("KunderaCoreExmples", + "CassandraEntitySimple"); + cf_def.column_type = "Standard"; + client.system_add_column_family(cf_def); + + getEntityManagerFactory("validate"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), + // null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = client.describe_keyspace("KunderaCoreExmples"); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.column_type); + List columns = new ArrayList(); + columns.add("AGE"); + columns.add("PERSON_NAME"); + + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + Assert.assertFalse(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertNull(columnDef.index_name); + } + } + } + catch (SchemaGenerationException e) + { + List errors = new ArrayList(); + errors.add("com.impetus.kundera.configure.schema.SchemaGenerationException: Column AGE does not exist in column family CassandraEntitySimple"); + errors.add("com.impetus.kundera.configure.schema.SchemaGenerationException: Column PERSON_NAME does not exist in column family CassandraEntitySimple"); + // errors.add("column family " + "CassandraEntitySimple " + + // " does not exist in keyspace " + // + "KunderaCassandraExamples" + ""); + Assert.assertTrue(errors.contains(e.getMessage())); + + } + catch (InvalidRequestException e1) + { + Assert.fail("failed caused by:" + e1.getMessage()); + } + catch (TException e1) + { + Assert.fail("failed caused by:" + e1.getMessage()); + } + catch (SchemaDisagreementException e) + { + Assert.fail("failed caused by:" + e.getMessage()); + } + catch (NotFoundException e) + { + Assert.fail("failed caused by:" + e.getMessage()); + } + catch (UnsupportedEncodingException e) + { + Assert.fail("failed caused by:" + e.getMessage()); + } + } + + @Test + public void validateInvalidSchema() throws NotFoundException, InvalidRequestException, TException, + SchemaDisagreementException, UnsupportedEncodingException + { + try + { + CassandraCli.createKeySpace("KunderaCoreExmples"); + client.set_keyspace("KunderaCoreExmples"); + org.apache.cassandra.thrift.CfDef cf_def = new org.apache.cassandra.thrift.CfDef("KunderaCoreExmples", + "CassandraEntitySimple"); + cf_def.column_type = "Standard"; + List column_metadata = new ArrayList(); + ColumnDef def = new ColumnDef(); + def.setName("AGE".getBytes()); + def.setValidation_class("UTF8Type"); + def.setIndex_type(IndexType.KEYS); + + ColumnDef def1 = new ColumnDef(); + def1.setName("PERSON_NAME".getBytes()); + def1.setValidation_class("BytesType"); + def1.setIndex_type(IndexType.KEYS); + + column_metadata.add(def1); + column_metadata.add(def); + + cf_def.setColumn_metadata(column_metadata); + client.system_add_column_family(cf_def); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = client.describe_keyspace("KunderaCoreExmples"); + Assert.assertEquals(1, ksDef.getCf_defs().size()); + Assert.assertEquals(2, ksDef.getCf_defs().get(0).getColumn_metadata().size()); + + getEntityManagerFactory("validate"); + // schemaManager = new + // CassandraSchemaManager(PelopsClientFactory.class.getName(), + // null); + // schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCassandraExamples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("CassandraEntitySimple", "KunderaCassandraExamples")); + ksDef = client.describe_keyspace("KunderaCassandraExamples"); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("CassandraEntitySimple", cfDef.getName()); + + Assert.assertEquals("Standard", cfDef.getColumn_type()); + + List columns = new ArrayList(); + columns.add("AGE"); + columns.add("PERSON_NAME"); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(CassandraEntitySimple.class); + for (ColumnDef columnDef : cfDef.getColumn_metadata()) + { + Assert.assertTrue(columnDef.isSetIndex_type()); + Assert.assertTrue(columns.contains(new String(columnDef.getName(), Constants.ENCODING))); + Assert.assertNotNull(columnDef.index_name); + } + } + } + catch (SchemaGenerationException sgex) + { + List errors = new ArrayList(); + errors.add("com.impetus.kundera.configure.schema.SchemaGenerationException: Column AGE does not exist in column family CassandraEntitySimple"); + errors.add("com.impetus.kundera.configure.schema.SchemaGenerationException: Column PERSON_NAME does not exist in column family CassandraEntitySimple"); + errors.add("com.impetus.kundera.configure.schema.SchemaGenerationException: column family CassandraEntitySimple does not exist in keyspace KunderaCoreExmples"); + Assert.assertTrue(errors.contains(sgex.getMessage().trim())); + } + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + ClientMetadata clientMetadata = new ClientMetadata(); + Map props = new HashMap(); + String persistenceUnit = "CassandraSchemaOperationTest"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, PelopsClientFactory.class.getName()); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaCoreExmples"); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "lucene"); + + clientMetadata.setLuceneIndexDir("lucene"); + } + else + { + + clientMetadata.setLuceneIndexDir(null); + } + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("CassandraSchemaOperationTest", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(CassandraEntitySimple.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(CassandraEntitySimple.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(CassandraEntitySimple.class, m); + + IndexProcessor indexProcessor = new IndexProcessor(); + indexProcessor.process(CassandraEntitySimple.class, m); + + m.setPersistenceUnit(persistenceUnit); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(CassandraEntitySimple.class, m); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + +// KunderaMetadata.INSTANCE.addClientMetadata(persistenceUnit, clientMetadata); + + String[] persistenceUnits = new String[] { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + + configuration.configure(); + // EntityManagerFactoryImpl impl = new + // EntityManagerFactoryImpl(puMetadata, props); + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassanrdaGeneratedIdSchemaTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassanrdaGeneratedIdSchemaTest.java new file mode 100644 index 000000000..30f2224e9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/CassanrdaGeneratedIdSchemaTest.java @@ -0,0 +1,103 @@ +package com.impetus.client.schemamanager; + +import java.util.List; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.persistence.CassandraCli; + +public class CassanrdaGeneratedIdSchemaTest +{ + private EntityManagerFactory emf; + + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + emf = Persistence.createEntityManagerFactory("cassandra_generated_id"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + } + + @Test + public void test() + { + try + { + KsDef ksDef = CassandraCli.client.describe_keyspace("kunderaGeneratedId"); + Assert.assertNotNull(ksDef); + Assert.assertEquals(13, ksDef.getCf_defsSize()); + int count = 0; + for (CfDef cfDef : ksDef.cf_defs) + { + if (cfDef.getName().equals("kundera_sequences")) + { + Assert.assertTrue(cfDef.getColumn_type().equals("Standard")); + Assert.assertTrue(cfDef.getDefault_validation_class().equals(CounterColumnType.class.getName())); + count++; + continue; + } + if (cfDef.getName().equals("kundera")) + { + Assert.assertTrue(cfDef.getColumn_type().equals("Standard")); + Assert.assertTrue(cfDef.getDefault_validation_class().equals(CounterColumnType.class.getName())); + count++; + } + else + { + Assert.assertTrue(cfDef.getColumn_type().equals("Standard")); + List columnDefs = cfDef.getColumn_metadata(); + Assert.assertEquals(1, columnDefs.size()); + count++; + } + + } + Assert.assertEquals(13, count); + } + catch (NotFoundException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (TException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Actor.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Actor.java new file mode 100644 index 000000000..3c0151506 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Actor.java @@ -0,0 +1,127 @@ +/** + * + */ +package com.impetus.client.schemamanager.entites; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "Actor", schema = "KunderaCoreExmples@CassandraSchemaOperationTest") +public class Actor +{ + @Id + @Column(name = "actor_id") + private String actorId; + + // Element collection, will persist co-located + @ElementCollection + @CollectionTable(name = "movie") + private List movies; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FRIEND_ID") + private List friends; // List of users whom I follow + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FOLLOWER_ID") + private List followers; // List of users who are following me + + /** + * @return the actorId + */ + public String getActorId() + { + return actorId; + } + + /** + * @param actorId + * the actorId to set + */ + public void setActorId(String actorId) + { + this.actorId = actorId; + } + + /** + * @return the tweets + */ + public List getTweets() + { + return movies; + } + + /** + * @param movies + * the tweets to set + */ + public void addTweet(Movie tweet) + { + if (this.movies == null || this.movies.isEmpty()) + { + this.movies = new ArrayList(); + } + this.movies.add(tweet); + } + + /** + * @return the friends + */ + public List getFriends() + { + return friends; + } + + /** + * @param friends + * the friends to set + */ + public void addFriend(Actor friend) + { + if (this.friends == null || this.friends.isEmpty()) + { + this.friends = new ArrayList(); + } + this.friends.add(friend); + } + + /** + * @return the followers + */ + public List getFollowers() + { + return followers; + } + + /** + * @param followers + * the followers to set + */ + public void addFollower(Actor follower) + { + if (this.followers == null || this.followers.isEmpty()) + { + this.followers = new ArrayList(); + } + + this.followers.add(follower); + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ActorTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ActorTest.java new file mode 100644 index 000000000..2877357e7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ActorTest.java @@ -0,0 +1,178 @@ +/** + * + */ +package com.impetus.client.schemamanager.entites; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.apache.cassandra.thrift.Cassandra; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.cassandra.pelops.PelopsClientFactory; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.IndexProcessor; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep Mishra + * + */ +public class ActorTest +{ + /** The configuration. */ + private SchemaConfiguration configuration; + + /** Configure schema manager. */ + private SchemaManager schemaManager; + + private Cassandra.Client client; + + private final boolean useLucene = false; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + configuration = new SchemaConfiguration(null, "CassandraSchemaOperationTest"); + CassandraCli.cassandraSetUp(); + CassandraCli cli = new CassandraCli(); + client = cli.getClient(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + CassandraCli.dropKeySpace("KunderaCoreExmples"); + + } + + @Test + public void test() throws NotFoundException, InvalidRequestException, TException, UnsupportedEncodingException + { + getEntityManagerFactory("create"); +// schemaManager = new CassandraSchemaManager(PelopsClientFactory.class.getName(), null); +// schemaManager.exportSchema(); + + Assert.assertTrue(CassandraCli.keyspaceExist("KunderaCoreExmples")); + Assert.assertTrue(CassandraCli.columnFamilyExist("Actor", "KunderaCoreExmples")); + org.apache.cassandra.thrift.KsDef ksDef = new KsDef(); + ksDef = client.describe_keyspace("KunderaCoreExmples"); + Assert.assertEquals(1, ksDef.getCf_defs().size()); + for (org.apache.cassandra.thrift.CfDef cfDef : ksDef.getCf_defs()) + { + Assert.assertEquals("Actor", cfDef.getName()); + + Assert.assertEquals("Super", cfDef.column_type); + } + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + ClientMetadata clientMetadata = new ClientMetadata(); + Map props = new HashMap(); + String persistenceUnit = "CassandraSchemaOperationTest"; + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, PelopsClientFactory.class.getName()); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaCoreExmples"); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "/home/impadmin/lucene"); + + clientMetadata.setLuceneIndexDir("/home/impadmin/lucene"); + } + else + { + + clientMetadata.setLuceneIndexDir(null); + } + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("CassandraSchemaOperationTest", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(Actor.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(Actor.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(Actor.class, m); + + IndexProcessor indexProcessor = new IndexProcessor(); + indexProcessor.process(Actor.class, m); + + m.setPersistenceUnit(persistenceUnit); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(Actor.class, m); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + +// KunderaMetadata.INSTANCE.addClientMetadata(persistenceUnit, clientMetadata); + + String[] persistenceUnits = new String[] { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + + configuration.configure(); + // EntityManagerFactoryImpl impl = new + // EntityManagerFactoryImpl(puMetadata, props); + return null; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEmbeddedPersonUniMto1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEmbeddedPersonUniMto1.java new file mode 100644 index 000000000..6693eefef --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEmbeddedPersonUniMto1.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonUniMto1. + */ +@Entity +@Table(name = "CassandraEmbeddedPersonUniMto1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEmbeddedPersonUniMto1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The address. */ + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private CassandraEntityAddressUniMTo1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressUniMTo1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(CassandraEntityAddressUniMTo1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1FK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1FK.java new file mode 100644 index 000000000..fafa9bf78 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1FK.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressBi1To1FK. + */ +@Entity +@Table(name = "CassandraEntityAddressBi1To1FK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressBi1To1FK +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** The person. */ + @OneToOne(mappedBy = "address") + private CassandraEntityPersonBi1To1FK person; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + + /** + * Gets the person. + * + * @return the person + */ + public CassandraEntityPersonBi1To1FK getPerson() + { + return person; + } + + /** + * Sets the person. + * + * @param person + * the new person + */ + public void setPerson(CassandraEntityPersonBi1To1FK person) + { + this.person = person; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1PK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1PK.java new file mode 100644 index 000000000..3c830e460 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1To1PK.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressBi1To1PK. + */ +@Entity +@Table(name = "CassandraEntityAddressBi1To1PK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressBi1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The address id. */ + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** The person. */ + @OneToOne(mappedBy = "address", fetch = FetchType.LAZY) + private CassandraEntityPersonBi1To1PK person; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + + /** + * Gets the person. + * + * @return the person + */ + public CassandraEntityPersonBi1To1PK getPerson() + { + return person; + } + + /** + * Sets the person. + * + * @param person + * the new person + */ + public void setPerson(CassandraEntityPersonBi1To1PK person) + { + this.person = person; + } + +} \ No newline at end of file diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1ToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1ToM.java new file mode 100644 index 000000000..448830e7c --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBi1ToM.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressBi1ToM. + */ +@Entity +@Table(name = "CassandraEntityAddressBi1ToM", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressBi1ToM +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** The person. */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "PERSON_ID") + private CassandraEntityPersonBi1ToM person; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + + /** + * Gets the person. + * + * @return the person + */ + public CassandraEntityPersonBi1ToM getPerson() + { + return person; + } + + /** + * Sets the person. + * + * @param person + * the new person + */ + public void setPerson(CassandraEntityPersonBi1ToM person) + { + this.person = person; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBiMTo1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBiMTo1.java new file mode 100644 index 000000000..7309b5e60 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressBiMTo1.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressBiMTo1. + */ +@Entity +@Table(name = "CassandraEntityAddressBiMTo1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressBiMTo1 +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** The people. */ + @OneToMany(mappedBy = "address", fetch = FetchType.LAZY) + private Set people; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + + /** + * Gets the people. + * + * @return the people + */ + public Set getPeople() + { + return people; + } + + /** + * Sets the people. + * + * @param people + * the new people + */ + public void setPeople(Set people) + { + this.people = people; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1.java new file mode 100644 index 000000000..c2051cd3d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressUni1To1. + */ +@Entity +@Table(name = "CassandraEntityAddressUni1To1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressUni1To1 +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1PK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1PK.java new file mode 100644 index 000000000..0f5514a40 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1To1PK.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressUni1To1PK. + */ +@Entity +@Table(name = "CassandraEntityAddressUni1To1PK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressUni1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The address id. */ + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1ToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1ToM.java new file mode 100644 index 000000000..1ec16d86f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUni1ToM.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressUni1ToM. + */ +@Entity +@Table(name = "CassandraEntityAddressUni1ToM", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressUni1ToM +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUniMTo1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUniMTo1.java new file mode 100644 index 000000000..1e0f2cd48 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityAddressUniMTo1.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class CassandraEntityAddressUniMTo1. + */ +@Entity +@Table(name = "CassandraEntityAddressUniMTo1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityAddressUniMTo1 +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityHabitatUniMToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityHabitatUniMToM.java new file mode 100644 index 000000000..6d055e6c9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityHabitatUniMToM.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraEntityHabitatUniMToM", schema = "KunderaCassandraMTMExamples@cassandra") +public class CassandraEntityHabitatUniMToM +{ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + @Column(name = "STREET") + private String street; + + public String getAddressId() + { + return addressId; + } + + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + public String getStreet() + { + return street; + } + + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1FK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1FK.java new file mode 100644 index 000000000..fd93799c5 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1FK.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonBi1To1FK. + */ +@Entity +@Table(name = "CassandraEntityPersonBi1To1FK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonBi1To1FK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private CassandraEntityAddressBi1To1FK address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressBi1To1FK getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the new address + */ + public void setAddress(CassandraEntityAddressBi1To1FK address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1PK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1PK.java new file mode 100644 index 000000000..64fd7748d --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1To1PK.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonBi1To1PK. + */ +@Entity +@Table(name = "CassandraEntityPersonBi1To1PK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonBi1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) + @PrimaryKeyJoinColumn + private CassandraEntityAddressBi1To1PK address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressBi1To1PK getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the new address + */ + public void setAddress(CassandraEntityAddressBi1To1PK address) + { + this.address = address; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1ToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1ToM.java new file mode 100644 index 000000000..d40583674 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBi1ToM.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonBi1ToM. + */ +@Entity +@Table(name = "CassandraEntityPersonBi1ToM", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonBi1ToM +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The addresses. */ + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person") + private Set addresses; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Gets the addresses. + * + * @return the addresses + */ + public Set getAddresses() + { + return addresses; + } + + /** + * Sets the addresses. + * + * @param addresses + * the new addresses + */ + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBiMTo1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBiMTo1.java new file mode 100644 index 000000000..43eace9f2 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonBiMTo1.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + + + +/** + * The Class CassandraEntityPersonBiMTo1. + */ +@Entity +@Table(name = "CassandraEntityPersonBiMTo1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonBiMTo1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The address. */ + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private CassandraEntityAddressBiMTo1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressBiMTo1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the new address + */ + public void setAddress(CassandraEntityAddressBiMTo1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1.java new file mode 100644 index 000000000..b4daaf9a7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonUni1To1. + */ +@Entity +@Table(name = "CassandraEntityPersonUni1To1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonUni1To1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private CassandraEntityAddressUni1To1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressUni1To1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(CassandraEntityAddressUni1To1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1PK.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1PK.java new file mode 100644 index 000000000..c5933c2f0 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1To1PK.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonUni1To1PK. + */ +@Entity +@Table(name = "CassandraEntityPersonUni1To1PK", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonUni1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + CassandraPersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) + @PrimaryKeyJoinColumn + private CassandraEntityAddressUni1To1PK address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressUni1To1PK getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(CassandraEntityAddressUni1To1PK address) + { + this.address = address; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1ToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1ToM.java new file mode 100644 index 000000000..b225b48b7 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUni1ToM.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * The Class CassandraEntityPersonUni1ToM. + */ +@Entity +@Table(name = "CassandraEntityPersonUni1ToM", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntityPersonUni1ToM +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** The addresses. */ + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "PERSON_ID") + private Set addresses; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the addresses. + * + * @return the addresses + */ + public Set getAddresses() + { + return addresses; + } + + /** + * Sets the addresses. + * + * @param addresses + * the addresses to set + */ + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUniMto1.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUniMto1.java new file mode 100644 index 000000000..9a5871088 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonUniMto1.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * The Class CassandraEntityPersonUniMto1. + */ +@Entity +@Table(name = "CassandraEntityPersonUniMto1", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class CassandraEntityPersonUniMto1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The address. */ + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private CassandraEntityAddressUniMTo1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the address. + * + * @return the address + */ + public CassandraEntityAddressUniMTo1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(CassandraEntityAddressUniMTo1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonnelUniMToM.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonnelUniMToM.java new file mode 100644 index 000000000..efc47f508 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntityPersonnelUniMToM.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "CassandraEntityPersonnelUniMToM", schema = "KunderaCassandraMTMExamples@cassandra") +public class CassandraEntityPersonnelUniMToM +{ + @Id + @Column(name = "PERSON_ID") + private String personId; + + @Column(name = "PERSON_NAME") + private String personName; + + @Embedded + CassandraPersonalData personalData; + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinTable(name = "PERSONNEL_ADDRESS", joinColumns = { @JoinColumn(name = "PERSON_ID") }, inverseJoinColumns = { @JoinColumn(name = "ADDRESS_ID") }) + private Set addresses; + + public String getPersonId() + { + return personId; + } + + public String getPersonName() + { + return personName; + } + + public void setPersonName(String personName) + { + this.personName = personName; + } + + public void setPersonId(String personId) + { + this.personId = personId; + } + + public Set getAddresses() + { + return addresses; + } + + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } + + /** + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySimple.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySimple.java new file mode 100644 index 000000000..28236b874 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySimple.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * The Class CassandraEntitySimple. + */ +@Entity +@Table(name = "CassandraEntitySimple", schema = "KunderaCoreExmples@CassandraSchemaOperationTest") +@IndexCollection(columns = { @Index(name = "personName", type = "KEYS"), @Index(name = "age", type = "KEYS") }) +public class CassandraEntitySimple +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySuper.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySuper.java new file mode 100644 index 000000000..bb6eb3f07 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraEntitySuper.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class CassandraEntitySuper. + */ +@Entity +@Table(name = "CassandraEntitySuper", schema = "CassandraSchemaManagerTest@CassandraSchemaManager") +public class CassandraEntitySuper +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private CassandraPersonalData personalData; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public CassandraPersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(CassandraPersonalData personalData) + { + this.personalData = personalData; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraPersonalData.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraPersonalData.java new file mode 100644 index 000000000..15edad344 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/CassandraPersonalData.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * The Class CassandraPersonalData. + */ +@Embeddable +public class CassandraPersonalData +{ + + /** The website. */ + @Column(name = "p_website") + private String website; + + /** The email. */ + @Column(name = "p_email") + private String email; + + /** The yahoo id. */ + @Column(name = "p_yahoo_id") + private String yahooId; + + /** + * Instantiates a new cassandra personal data. + */ + public CassandraPersonalData() + { + + } + + /** + * Instantiates a new cassandra personal data. + * + * @param website + * the website + * @param email + * the email + * @param yahooId + * the yahoo id + */ + public CassandraPersonalData(String website, String email, String yahooId) + { + this.website = website; + this.email = email; + this.yahooId = yahooId; + } + + /** + * Gets the website. + * + * @return the website + */ + public String getWebsite() + { + return website; + } + + /** + * Sets the website. + * + * @param website + * the new website + */ + public void setWebsite(String website) + { + this.website = website; + } + + /** + * Gets the email. + * + * @return the email + */ + public String getEmail() + { + return email; + } + + /** + * Sets the email. + * + * @param email + * the email to set + */ + public void setEmail(String email) + { + this.email = email; + } + + /** + * Gets the yahoo id. + * + * @return the yahoo id + */ + public String getYahooId() + { + return yahooId; + } + + /** + * Sets the yahoo id. + * + * @param yahooId + * the new yahoo id + */ + public void setYahooId(String yahooId) + { + this.yahooId = yahooId; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Doctor.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Doctor.java new file mode 100644 index 000000000..c13e3a950 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Doctor.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * @author Kuldeep Mishra + * @version 1.0 + * + */ +@Entity +@Table(name = "DOCTOR", schema = "KunderaExamples@secIdxCassandraTest") +@IndexCollection(columns = { @Index(name = "age"), @Index(name = "key") }) +public class Doctor +{ + @Id + private String id; + + @Column + private String name; + + @Column + private long age; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public long getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(long age) + { + this.age = age; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/InvalidCounterColumnEntity.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/InvalidCounterColumnEntity.java new file mode 100644 index 000000000..6daf10705 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/InvalidCounterColumnEntity.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "InvalidCounterColumnEntity", schema = "KunderaCounterColumn@cassandraProperties") +public class InvalidCounterColumnEntity +{ + + @Id + private int id; + + @Column + private long counter; + + @Column + private String lCounter; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the counter + */ + public long getCounter() + { + return counter; + } + + /** + * @param counter + * the counter to set + */ + public void setCounter(long counter) + { + this.counter = counter; + } + + /** + * @return the lCounter + */ + public String getlCounter() + { + return lCounter; + } + + /** + * @param lCounter + * the lCounter to set + */ + public void setlCounter(String lCounter) + { + this.lCounter = lCounter; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Movie.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Movie.java new file mode 100644 index 000000000..9c65df26f --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/Movie.java @@ -0,0 +1,79 @@ +/** + * + */ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * @author Kuldeep Mishra + * + */ +@Embeddable +@IndexCollection(columns = { @Index(name = "title"), @Index(name = "released_year") }) +public class Movie +{ + @Column(name = "movie_id") + private String movieId; + + @Column(name = "title") + private String title; + + @Column(name = "released_year") + private String releasedYear; + + /** + * @return the movieId + */ + public String getMovieId() + { + return movieId; + } + + /** + * @param movieId + * the movieId to set + */ + public void setMovieId(String movieId) + { + this.movieId = movieId; + } + + /** + * @return the title + */ + public String getTitle() + { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the releasedYear + */ + public String getReleasedYear() + { + return releasedYear; + } + + /** + * @param releasedYear + * the releasedYear to set + */ + public void setReleasedYear(String releasedYear) + { + this.releasedYear = releasedYear; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ValidCounterColumnFamily.java b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ValidCounterColumnFamily.java new file mode 100644 index 000000000..9757aedb5 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/schemamanager/entites/ValidCounterColumnFamily.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.schemamanager.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "ValidCounterColumnFamily", schema = "KunderaCounterColumn@cassandraProperties") +public class ValidCounterColumnFamily +{ + + @Id + private int id; + + @Column + private long counter; + + @Column + private Long lCounter; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the counter + */ + public long getCounter() + { + return counter; + } + + /** + * @param counter + * the counter to set + */ + public void setCounter(long counter) + { + this.counter = counter; + } + + /** + * @return the lCounter + */ + public Long getlCounter() + { + return lCounter; + } + + /** + * @param lCounter + * the lCounter to set + */ + public void setlCounter(Long lCounter) + { + this.lCounter = lCounter; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraSuperColumnDatatypeTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraSuperColumnDatatypeTest.java new file mode 100644 index 000000000..d38157d78 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraSuperColumnDatatypeTest.java @@ -0,0 +1,920 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.twitter; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.twitter.entities.ProfessionalDetailCassandra; +import com.impetus.client.twitter.entities.UserCassandra; +import com.impetus.kundera.Constants; + +/** + * Test case for data type compatibility testing for Twissandra + * + * @author amresh.singh + */ +public class TwissandraSuperColumnDatatypeTest extends TwitterTestBaseCassandra +{ + /** The Constant LOG. */ + private static final Logger log = LoggerFactory.getLogger(TwissandraSuperColumnDatatypeTest.class); + + @Before + public void setUp() throws Exception + { + setUpInternal(persistenceUnit); + } + + @Test + public void onExecute() throws Exception + { + // Insert, Find and Update + addAllUserInfo(); + getUserById(); + updateUser(); + + // Queries for all data types + getUserByProfessionId(); + getUserByDepartmentName(); + getExceptionalUsers(); + getUserByAge(); + getUserByGrade(); + getUserByDigitalSignature(); + getUserByRating(); + getUserByCompliance(); + getUserByHeight(); + getUserByEnrolmentDate(); + getUserByEnrolmentTime(); + getUserByJoiningDateAndTime(); + + getUserByYearsSpent(); + getUserByUniqueId(); + getUserByMonthlySalary(); + getUserByBirthday(); + getUserByBirthtime(); + getUserByAnniversary(); + getUserByJobAttempts(); + getUserByAccumulatedWealth(); + getUserByGraduationDay(); + + // Remove Users + removeUsers(); + } + + @After + public void tearDown() throws Exception + { + tearDownInternal(); + } + + @Override + void startServer() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + log.error(e.getMessage(),e); + } + catch (TException e) + { + log.error(e.getMessage(),e); + } + catch (InvalidRequestException e) + { + log.error(e.getMessage(),e); + } + catch (UnavailableException e) + { + log.error(e.getMessage(),e); + } + catch (TimedOutException e) + { + log.error(e.getMessage(),e); + } + catch (SchemaDisagreementException e) + { + log.error(e.getMessage(),e); + } + } + + /************** Queries on Professional Data ****************/ + void getUserByProfessionId() + { + // User 1 + twitter.createEntityManager(); + List users = twitter.findUserByProfessionId(1234567); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(1234567, pd.getProfessionId()); + twitter.closeEntityManager(); + + // User2 + twitter.createEntityManager(); + List users2 = twitter.findUserByProfessionId(1234568); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(1234568, pd2.getProfessionId()); + twitter.closeEntityManager(); + } + + void getUserByDepartmentName() + { + // User 1 + twitter.createEntityManager(); + List users = twitter.findUserByDepartment("Labs"); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals("Labs", pd.getDepartmentName()); + twitter.closeEntityManager(); + + // User2 + twitter.createEntityManager(); + List users2 = twitter.findUserByDepartment("ODC"); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals("ODC", pd2.getDepartmentName()); + twitter.closeEntityManager(); + } + + void getExceptionalUsers() + { + // User 1 + twitter.createEntityManager(); + List users = twitter.findExceptionalUsers(); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId2, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(true, pd.isExceptional()); + twitter.closeEntityManager(); + + } + + void getUserByAge() + { + twitter.createEntityManager(); + List users = twitter.findUserByAge(31); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(31, pd.getAge()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByAge(32); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(32, pd2.getAge()); + twitter.closeEntityManager(); + } + + void getUserByGrade() + { + twitter.createEntityManager(); + List users = twitter.findUserByGrade('C'); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals('C', pd.getGrade()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByGrade('A'); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals('A', pd2.getGrade()); + twitter.closeEntityManager(); + } + + void getUserByDigitalSignature() + { + twitter.createEntityManager(); + List users = twitter.findUserByDigitalSignature((byte) 8); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals((byte) 8, pd.getDigitalSignature()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByDigitalSignature((byte) 10); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals((byte) 10, pd2.getDigitalSignature()); + twitter.closeEntityManager(); + } + + void getUserByRating() + { + twitter.createEntityManager(); + List users = twitter.findUserByRating((short) 5); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals((short) 5, pd.getRating()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByRating((short) 8); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals((short) 8, pd2.getRating()); + twitter.closeEntityManager(); + } + + void getUserByCompliance() + { + twitter.createEntityManager(); + List users = twitter.findUserByCompliance((float) 10.0); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals((float) 10.0, pd.getCompliance(), 0.0); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByCompliance((float) 9.80); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals((float) 9.80, pd2.getCompliance(), 0.0); + twitter.closeEntityManager(); + } + + void getUserByHeight() + { + twitter.createEntityManager(); + List users = twitter.findUserByHeight(163.12); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(163.12, pd.getHeight(), 0.0); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByHeight(323.3); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(323.3, pd2.getHeight(), 0.0); + twitter.closeEntityManager(); + + } + + void getUserByEnrolmentDate() + { + twitter.createEntityManager(); + List users = twitter.findUserByEnrolmentDate(new Date(Long.parseLong("1344079065781"))); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Date(Long.parseLong("1344079065781")), pd.getEnrolmentDate()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByEnrolmentDate(new Date(Long.parseLong("1344079063412"))); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Date(Long.parseLong("1344079063412")), pd2.getEnrolmentDate()); + twitter.closeEntityManager(); + + } + + void getUserByEnrolmentTime() + { + twitter.createEntityManager(); + List users = twitter.findUserByEnrolmentTime(new Date(Long.parseLong("1344079067623"))); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Date(Long.parseLong("1344079067623")), pd.getEnrolmentTime()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByEnrolmentTime(new Date(Long.parseLong("1344079068266"))); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Date(Long.parseLong("1344079068266")), pd2.getEnrolmentTime()); + twitter.closeEntityManager(); + + } + + void getUserByJoiningDateAndTime() + { + twitter.createEntityManager(); + List users = twitter.findUserByJoiningDateAndTime(new Date(Long.parseLong("1344079069105"))); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Date(Long.parseLong("1344079069105")), pd.getJoiningDateAndTime()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByJoiningDateAndTime(new Date(Long.parseLong("1344079061078"))); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Date(Long.parseLong("1344079061078")), pd2.getJoiningDateAndTime()); + twitter.closeEntityManager(); + } + + void getUserByYearsSpent() + { + twitter.createEntityManager(); + List users = twitter.findUserByYearsSpent(new Integer(2)); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Integer(2), pd.getYearsSpent()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByYearsSpent(new Integer(5)); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Integer(5), pd2.getYearsSpent()); + twitter.closeEntityManager(); + } + + void getUserByUniqueId() + { + twitter.createEntityManager(); + List users = twitter.findUserByUniqueId(new Long(3634521523423L)); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Long(3634521523423L), pd.getUniqueId()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByUniqueId(new Long(25423452343L)); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Long(25423452343L), pd2.getUniqueId()); + twitter.closeEntityManager(); + } + + void getUserByMonthlySalary() + { + twitter.createEntityManager(); + List users = twitter.findUserByMonthlySalary(new Double(0.23452342343)); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new Double(0.23452342343), pd.getMonthlySalary()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByMonthlySalary(new Double(0.76452343)); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new Double(0.76452343), pd2.getMonthlySalary()); + twitter.closeEntityManager(); + } + + void getUserByBirthday() + { + twitter.createEntityManager(); + List users = twitter.findUserByBirthday(new java.sql.Date(new Date(Long + .parseLong("1344079061111")).getTime())); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new java.sql.Date(new Date(Long.parseLong("1344079061111")).getTime()), pd.getBirthday()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByBirthday(new java.sql.Date(new Date(Long + .parseLong("1344079064444")).getTime())); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new java.sql.Date(new Date(Long.parseLong("1344079064444")).getTime()), pd2.getBirthday()); + twitter.closeEntityManager(); + } + + void getUserByBirthtime() + { + twitter.createEntityManager(); + List users = twitter.findUserByBirthtime(new java.sql.Time(new Date(Long + .parseLong("1344079062222")).getTime())); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new java.sql.Time(new Date(Long.parseLong("1344079062222")).getTime()), pd.getBirthtime()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByBirthtime(new java.sql.Time(new Date(Long + .parseLong("1344079065555")).getTime())); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new java.sql.Time(new Date(Long.parseLong("1344079065555")).getTime()), pd2.getBirthtime()); + twitter.closeEntityManager(); + } + + void getUserByAnniversary() + { + twitter.createEntityManager(); + List users = twitter.findUserByAnniversary(new java.sql.Timestamp(new Date(Long + .parseLong("13440790653333")).getTime())); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new java.sql.Timestamp(new Date(Long.parseLong("13440790653333")).getTime()), + pd.getAnniversary()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByAnniversary(new java.sql.Timestamp(new Date(Long + .parseLong("1344079066666")).getTime())); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new java.sql.Timestamp(new Date(Long.parseLong("1344079066666")).getTime()), + pd2.getAnniversary()); + twitter.closeEntityManager(); + } + + void getUserByJobAttempts() + { + twitter.createEntityManager(); + List users = twitter.findUserByJobAttempts(new BigInteger("123456789")); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new BigInteger("123456789"), pd.getJobAttempts()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByJobAttempts(new BigInteger("123456790")); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new BigInteger("123456790"), pd2.getJobAttempts()); + twitter.closeEntityManager(); + } + + void getUserByAccumulatedWealth() + { + twitter.createEntityManager(); + List users = twitter.findUserByAccumulatedWealth(new BigDecimal(123456789)); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(new BigDecimal(123456789), pd.getAccumulatedWealth()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List users2 = twitter.findUserByAccumulatedWealth(new BigDecimal(123456790)); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(new BigDecimal(123456790), pd2.getAccumulatedWealth()); + twitter.closeEntityManager(); + } + + void getUserByGraduationDay() + { + twitter.createEntityManager(); + + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(1344079067777l)); + List users = twitter.findUserByGraduationDay(cal); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + ProfessionalDetailCassandra pd = user.getProfessionalDetail(); + Assert.assertNotNull(pd); + Assert.assertEquals(cal, pd.getGraduationDay()); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(new Date(1344079068888l)); + List users2 = twitter.findUserByGraduationDay(cal2); + Assert.assertNotNull(users2); + Assert.assertFalse(users2.isEmpty()); + Assert.assertTrue(users2.size() == 1); + UserCassandra user2 = users2.get(0); + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + ProfessionalDetailCassandra pd2 = user2.getProfessionalDetail(); + Assert.assertNotNull(pd2); + Assert.assertEquals(cal2, pd2.getGraduationDay()); + twitter.closeEntityManager(); + } + + @Override + void stopServer() + { + } + + @Override + void createSchema() throws InvalidRequestException, SchemaDisagreementException, TException + { + KsDef ksDef = null; + CfDef userCfDef = new CfDef(); + userCfDef.name = "USER"; + userCfDef.keyspace = keyspace; + userCfDef.column_type = "Super"; + userCfDef.setComparator_type("UTF8Type"); + userCfDef.setSubcomparator_type("AsciiType"); + userCfDef.setKey_validation_class("UTF8Type"); + + CfDef userIndexCfDef = new CfDef(); + userIndexCfDef.name = "USER" + Constants.INDEX_TABLE_SUFFIX; + userIndexCfDef.column_type = "Super"; + userIndexCfDef.keyspace = keyspace; + userCfDef.setKey_validation_class("AsciiType"); + + CfDef prefrenceCfDef = new CfDef(); + prefrenceCfDef.name = "PREFERENCE"; + prefrenceCfDef.keyspace = keyspace; + prefrenceCfDef.setComparator_type("UTF8Type"); + prefrenceCfDef.setDefault_validation_class("UTF8Type"); + prefrenceCfDef.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("WEBSITE_THEME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("PRIVACY_LEVEL".getBytes()), "UTF8Type"); + columnDef3.index_type = IndexType.KEYS; + prefrenceCfDef.addToColumn_metadata(columnDef); + prefrenceCfDef.addToColumn_metadata(columnDef3); + + CfDef externalLinkCfDef = new CfDef(); + externalLinkCfDef.name = "EXTERNAL_LINK"; + externalLinkCfDef.keyspace = keyspace; + externalLinkCfDef.setComparator_type("UTF8Type"); + externalLinkCfDef.setDefault_validation_class("UTF8Type"); + externalLinkCfDef.setKey_validation_class("UTF8Type"); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("LINK_TYPE".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("LINK_ADDRESS".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + ColumnDef columnDef4 = new ColumnDef(ByteBuffer.wrap("USER_ID".getBytes()), "UTF8Type"); + columnDef4.index_type = IndexType.KEYS; + externalLinkCfDef.addToColumn_metadata(columnDef1); + externalLinkCfDef.addToColumn_metadata(columnDef2); + externalLinkCfDef.addToColumn_metadata(columnDef4); + + /* + * CfDef userCfDef = new CfDef(); userCfDef.name = "USER"; + * userCfDef.keyspace = keyspace; userCfDef.column_type = "Super"; + * userCfDef.setComparator_type("UTF8Type"); + * userCfDef.setSubcomparator_type("AsciiType"); + * userCfDef.setKey_validation_class("UTF8Type"); + * + * CfDef userIndexCfDef = new CfDef(); userIndexCfDef.name = "USER" + + * Constants.INDEX_TABLE_SUFFIX; userIndexCfDef.column_type = "Super"; + * userIndexCfDef.keyspace = keyspace; + * userIndexCfDef.setKey_validation_class("UTF8Type"); + * + * CfDef prefrenceCfDef = new CfDef(); prefrenceCfDef.name = + * "PREFERENCE"; prefrenceCfDef.keyspace = keyspace; + * prefrenceCfDef.setComparator_type("UTF8Type"); + * prefrenceCfDef.setDefault_validation_class("UTF8Type"); ColumnDef + * columnDef = new + * ColumnDef(ByteBuffer.wrap("WEBSITE_THEME".getBytes()), "UTF8Type"); + * columnDef.index_type = IndexType.KEYS; ColumnDef columnDef3 = new + * ColumnDef(ByteBuffer.wrap("PRIVACY_LEVEL".getBytes()), "UTF8Type"); + * columnDef3.index_type = IndexType.KEYS; + * prefrenceCfDef.addToColumn_metadata(columnDef); + * prefrenceCfDef.addToColumn_metadata(columnDef3); + * + * CfDef externalLinkCfDef = new CfDef(); externalLinkCfDef.name = + * "EXTERNAL_LINK"; externalLinkCfDef.keyspace = keyspace; + * externalLinkCfDef.setComparator_type("UTF8Type"); + * externalLinkCfDef.setDefault_validation_class("UTF8Type"); ColumnDef + * columnDef1 = new ColumnDef(ByteBuffer.wrap("LINK_TYPE".getBytes()), + * "UTF8Type"); columnDef1.index_type = IndexType.KEYS; ColumnDef + * columnDef2 = new + * ColumnDef(ByteBuffer.wrap("LINK_ADDRESS".getBytes()), "UTF8Type"); + * columnDef2.index_type = IndexType.KEYS; ColumnDef columnDef4 = new + * ColumnDef(ByteBuffer.wrap("USER_ID".getBytes()), "UTF8Type"); + * columnDef4.index_type = IndexType.KEYS; + * externalLinkCfDef.addToColumn_metadata(columnDef1); + * externalLinkCfDef.addToColumn_metadata(columnDef2); + * externalLinkCfDef.addToColumn_metadata(columnDef4); + */ + + List cfDefs = new ArrayList(); + cfDefs.add(userCfDef); + cfDefs.add(userIndexCfDef); + cfDefs.add(prefrenceCfDef); + cfDefs.add(externalLinkCfDef); + try + { + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("USER")) + { + CassandraCli.client.system_drop_column_family("USER"); + } + if (cfDef1.getName().equalsIgnoreCase("USER" + Constants.INDEX_TABLE_SUFFIX)) + { + CassandraCli.client.system_drop_column_family("USER" + Constants.INDEX_TABLE_SUFFIX); + } + if (cfDef1.getName().equalsIgnoreCase("PREFERENCE")) + { + CassandraCli.client.system_drop_column_family("PREFERENCE"); + } + if (cfDef1.getName().equalsIgnoreCase("EXTERNAL_LINK")) + { + CassandraCli.client.system_drop_column_family("EXTERNAL_LINK"); + } + } + CassandraCli.client.system_add_column_family(userCfDef); + CassandraCli.client.system_add_column_family(userIndexCfDef); + CassandraCli.client.system_add_column_family(externalLinkCfDef); + CassandraCli.client.system_add_column_family(prefrenceCfDef); + } + catch (NotFoundException e) + { + ksDef = new KsDef(keyspace, SimpleStrategy.class.getSimpleName(), cfDefs); + + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.client.system_add_keyspace(ksDef); + } + catch (InvalidRequestException e) + { + log.error(e.getMessage(),e); + } + catch (TException e) + { + log.error(e.getMessage(),e); + } + } + + @Override + void deleteSchema() + { + CassandraCli.dropKeySpace(keyspace); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraTest.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraTest.java new file mode 100644 index 000000000..5d64360f5 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwissandraTest.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.cassandra.locator.SimpleStrategy; +import org.apache.cassandra.thrift.CfDef; +import org.apache.cassandra.thrift.ColumnDef; +import org.apache.cassandra.thrift.IndexType; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.KsDef; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.cassandra.thrift.TimedOutException; +import org.apache.cassandra.thrift.UnavailableException; +import org.apache.thrift.TException; +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.Constants; + +/** + * Test case for Cassandra. + * + * @author amresh.singh + */ +public class TwissandraTest extends TwitterTestBaseCassandra +{ + + /** The Constant LOG. */ + private static final Logger log = LoggerFactory.getLogger(TwissandraTest.class); + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + @Before + public void setUp() throws Exception + { + setUpInternal(persistenceUnit); + } + + @Test + @PerfTest(invocations = 10) + public void onExecute() throws Exception + { + executeTwissandraTest(); + } + + @After + public void tearDown() throws Exception + { + tearDownInternal(); + } + + @Override + void startServer() + { + try + { + CassandraCli.cassandraSetUp(); + } + catch (IOException e) + { + e.printStackTrace(); + } + catch (TException e) + { + e.printStackTrace(); + } + catch (InvalidRequestException e) + { + e.printStackTrace(); + } + catch (UnavailableException e) + { + e.printStackTrace(); + } + catch (TimedOutException e) + { + e.printStackTrace(); + } + catch (SchemaDisagreementException e) + { + e.printStackTrace(); + } + } + + @Override + void stopServer() + { + } + + @Override + void createSchema() throws InvalidRequestException, SchemaDisagreementException, TException + { + KsDef ksDef = null; + + CfDef userCfDef = new CfDef(); + userCfDef.name = "USER"; + userCfDef.keyspace = keyspace; + userCfDef.column_type = "Super"; + userCfDef.setComparator_type("UTF8Type"); + userCfDef.setSubcomparator_type("AsciiType"); + userCfDef.setKey_validation_class("UTF8Type"); + + CfDef userIndexCfDef = new CfDef(); + userIndexCfDef.name = "USER" + Constants.INDEX_TABLE_SUFFIX; + userIndexCfDef.column_type = "Super"; + userIndexCfDef.keyspace = keyspace; + userCfDef.setKey_validation_class("AsciiType"); + + CfDef prefrenceCfDef = new CfDef(); + prefrenceCfDef.name = "PREFERENCE"; + prefrenceCfDef.keyspace = keyspace; + prefrenceCfDef.setComparator_type("UTF8Type"); + prefrenceCfDef.setDefault_validation_class("UTF8Type"); + prefrenceCfDef.setKey_validation_class("UTF8Type"); + ColumnDef columnDef = new ColumnDef(ByteBuffer.wrap("WEBSITE_THEME".getBytes()), "UTF8Type"); + columnDef.index_type = IndexType.KEYS; + ColumnDef columnDef3 = new ColumnDef(ByteBuffer.wrap("PRIVACY_LEVEL".getBytes()), "UTF8Type"); + columnDef3.index_type = IndexType.KEYS; + prefrenceCfDef.addToColumn_metadata(columnDef); + prefrenceCfDef.addToColumn_metadata(columnDef3); + + CfDef externalLinkCfDef = new CfDef(); + externalLinkCfDef.name = "EXTERNAL_LINK"; + externalLinkCfDef.keyspace = keyspace; + externalLinkCfDef.setComparator_type("UTF8Type"); + externalLinkCfDef.setDefault_validation_class("UTF8Type"); + externalLinkCfDef.setKey_validation_class("UTF8Type"); + ColumnDef columnDef1 = new ColumnDef(ByteBuffer.wrap("LINK_TYPE".getBytes()), "UTF8Type"); + columnDef1.index_type = IndexType.KEYS; + ColumnDef columnDef2 = new ColumnDef(ByteBuffer.wrap("LINK_ADDRESS".getBytes()), "UTF8Type"); + columnDef2.index_type = IndexType.KEYS; + ColumnDef columnDef4 = new ColumnDef(ByteBuffer.wrap("USER_ID".getBytes()), "UTF8Type"); + columnDef4.index_type = IndexType.KEYS; + externalLinkCfDef.addToColumn_metadata(columnDef1); + externalLinkCfDef.addToColumn_metadata(columnDef2); + externalLinkCfDef.addToColumn_metadata(columnDef4); + + List cfDefs = new ArrayList(); + cfDefs.add(userCfDef); + cfDefs.add(userIndexCfDef); + cfDefs.add(prefrenceCfDef); + cfDefs.add(externalLinkCfDef); + try + { + ksDef = CassandraCli.client.describe_keyspace(keyspace); + CassandraCli.client.set_keyspace(keyspace); + List cfDefn = ksDef.getCf_defs(); + + for (CfDef cfDef1 : cfDefn) + { + + if (cfDef1.getName().equalsIgnoreCase("USER")) + { + CassandraCli.client.system_drop_column_family("USER"); + } + if (cfDef1.getName().equalsIgnoreCase("USER" + Constants.INDEX_TABLE_SUFFIX)) + { + CassandraCli.client.system_drop_column_family("USER" + Constants.INDEX_TABLE_SUFFIX); + } + if (cfDef1.getName().equalsIgnoreCase("PREFERENCE")) + { + CassandraCli.client.system_drop_column_family("PREFERENCE"); + } + if (cfDef1.getName().equalsIgnoreCase("EXTERNAL_LINK")) + { + CassandraCli.client.system_drop_column_family("EXTERNAL_LINK"); + } + } + CassandraCli.client.system_add_column_family(userCfDef); + CassandraCli.client.system_add_column_family(userIndexCfDef); + CassandraCli.client.system_add_column_family(externalLinkCfDef); + CassandraCli.client.system_add_column_family(prefrenceCfDef); + } + catch (NotFoundException e) + { + ksDef = new KsDef(keyspace, SimpleStrategy.class.getSimpleName(), cfDefs); + + // Set replication factor + if (ksDef.strategy_options == null) + { + ksDef.strategy_options = new LinkedHashMap(); + } + // Set replication factor, the value MUST be an integer + ksDef.strategy_options.put("replication_factor", "1"); + + CassandraCli.client.system_add_keyspace(ksDef); + } + catch (InvalidRequestException e) + { + log.error(e.getMessage()); + } + catch (TException e) + { + log.error(e.getMessage()); + } + } + + @Override + void deleteSchema() + { + /* + * LOG.warn( + * "Truncating Column families and finally dropping Keyspace KunderaExamples in Cassandra...." + * ); CassandraCli.dropColumnFamily("USER", keyspace); + * CassandraCli.dropColumnFamily("PREFERENCE", keyspace); + * CassandraCli.dropColumnFamily("EXTERNAL_LINKS", keyspace); + * CassandraCli.dropKeySpace(keyspace); + */ + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwitterTestBaseCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwitterTestBaseCassandra.java new file mode 100644 index 000000000..a0fe506f8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/TwitterTestBaseCassandra.java @@ -0,0 +1,601 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.apache.cassandra.thrift.InvalidRequestException; +import org.apache.cassandra.thrift.NotFoundException; +import org.apache.cassandra.thrift.SchemaDisagreementException; +import org.apache.thrift.TException; +import org.junit.Assert; + +import com.impetus.client.persistence.CassandraCli; +import com.impetus.client.twitter.dao.TwitterCassandra; +import com.impetus.client.twitter.dao.TwitterServiceCassandra; +import com.impetus.client.twitter.entities.ExternalLinkCassandra; +import com.impetus.client.twitter.entities.PersonalDetailCassandra; +import com.impetus.client.twitter.entities.PreferenceCassandra; +import com.impetus.client.twitter.entities.ProfessionalDetailCassandra; +import com.impetus.client.twitter.entities.TweetCassandra; +import com.impetus.client.twitter.entities.UserCassandra; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Test case for Cassandra Cassandra-cli commands for running with standalone + * cassandra server: ********** Cassandra-cli commands ************* drop + * keyspace KunderaExamples; create keyspace KunderaExamples; use + * KunderaExamples; create column family USER with column_type=Super and + * comparator=UTF8Type and subcomparator = AsciiType and + * key_validation_class=UTF8Type; create column family USER_INVRTD_IDX with + * column_type=Super and key_validation_class=UTF8Type; create column family + * PREFERENCE; create column family EXTERNAL_LINK with comparator=UTF8Type and + * default_validation_class=UTF8Type and key_validation_class=UTF8Type and + * column_metadata=[{column_name: USER_ID, validation_class:UTF8Type, + * index_type: KEYS}]; describe KunderaExamples; + * + * @author amresh.singh + */ +public abstract class TwitterTestBaseCassandra +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + public static final String persistenceUnit = "twissandraTest"; + + public static final String keyspace = "KunderaExamples"; + + /** The user id1. */ + String userId1; + + /** The user id2. */ + String userId2; + + /** The twitter. */ + protected TwitterCassandra twitter; + + /** + * Sets the up internal. + * + * @param persistenceUnitName + * the new up internal + * @throws Exception + * the exception + */ + protected void setUpInternal(String persistenceUnitName) throws Exception + { + userId1 = "0001"; + userId2 = "0002"; + + // Start Cassandra Server + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + // Create Schema + if (AUTO_MANAGE_SCHEMA) + { + CassandraCli.initClient(); + createSchema(); + } + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + twitter = new TwitterServiceCassandra(persistenceUnitName); + + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + /** + * Tear down internal. + * + * @throws Exception + * the exception + */ + protected void tearDownInternal() throws Exception + { + if (twitter != null) + { + twitter.close(); + } + + if (AUTO_MANAGE_SCHEMA) + { + deleteSchema(); + } + + // Stop Server + if (RUN_IN_EMBEDDED_MODE) + { + stopServer(); + } + } + + /** + * Execute suite. + */ + protected void executeTwissandraTest() + { + // Insert, Find and Update + addAllUserInfo(); + getUserById(); + updateUser(); + + // Queries + getPersonalDetailByName(); + getAllUsers(); + getTweetsByDevice(); + getTweetsByRelationshipAndDevice(); + getTweetsByUserIdAndDevice(); + + // Remove Users + removeUsers(); + } + + protected void addAllUserInfo() + { + UserCassandra user1 = buildUser1(); + UserCassandra user2 = buildUser2(); + + twitter.createEntityManager(); + twitter.addUser(user1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(user2); + twitter.closeEntityManager(); + } + + protected void getUserById() + { + twitter.createEntityManager(); + UserCassandra user1 = twitter.findUserById(userId1); + assertUser1(user1); + + UserCassandra user2 = twitter.findUserById(userId2); + assertUser2(user2); + } + + protected void updateUser() + { + twitter.createEntityManager(); + UserCassandra user1 = twitter.findUserById(userId1); + assertUser1(user1); + + user1.setPersonalDetail(new PersonalDetailCassandra("Vivek", "unknown", "Married")); + user1.addTweet(new TweetCassandra("My Third Tweet", "iPhone")); + twitter.mergeUser(user1); + + UserCassandra user1AfterMerge = twitter.findUserById(userId1); + + assertUpdatedUser1(user1AfterMerge); + + twitter.closeEntityManager(); + } + + protected void removeUsers() + { + twitter.createEntityManager(); + UserCassandra user1 = twitter.findUserById(userId1); + assertUpdatedUser1(user1); + + twitter.removeUser(user1); + + UserCassandra user1AfterRemoval = twitter.findUserById(userId1); + Assert.assertNull(user1AfterRemoval); + + UserCassandra user2 = twitter.findUserById(userId2); + assertUser2(user2); + + twitter.removeUser(user2); + + UserCassandra user2AfterRemoval = twitter.findUserById(userId2); + Assert.assertNull(user2AfterRemoval); + + twitter.closeEntityManager(); + + } + + protected void getAllUsers() + { + twitter.createEntityManager(); + List users = twitter.getAllUsers(); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertEquals(2, users.size()); + + for (UserCassandra u : users) + { + Assert.assertNotNull(u); + if (u.getUserId().equals(userId1)) + { + assertUpdatedUser1(u); + } + else if (u.getUserId().equals(userId2)) + { + assertUser2(u); + } + } + twitter.closeEntityManager(); + } + + /** + * Adds the users. + */ + protected void addUsers() + { + twitter.createEntityManager(); + twitter.addUser(userId1, "Amresh", "password1", "married"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(userId2, "Saurabh", "password2", "single"); + twitter.closeEntityManager(); + } + + /** + * Save preference. + */ + protected void savePreference() + { + twitter.createEntityManager(); + twitter.savePreference(userId1, new PreferenceCassandra("P1", "Motif", "2")); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.savePreference(userId2, new PreferenceCassandra("P2", "High Contrast", "3")); + twitter.closeEntityManager(); + } + + /** + * Adds the external links. + */ + protected void addExternalLinks() + { + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L1", "Facebook", "http://facebook.com/coolnerd"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L2", "LinkedIn", "http://linkedin.com/in/devilmate"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L3", "GooglePlus", "http://plus.google.com/inviteme"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry"); + twitter.closeEntityManager(); + } + + /** + * Adds the tweets. + */ + protected void addTweets() + { + twitter.createEntityManager(); + twitter.addTweet(userId1, "Here is my first tweet", "Web"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId1, "Second Tweet from me", "Mobile"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Saurabh tweets for the first time", "Phone"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Another tweet from Saurabh", "text"); + twitter.closeEntityManager(); + } + + /** + * User1 follows user2. + */ + protected void user1FollowsUser2() + { + twitter.createEntityManager(); + twitter.startFollowing(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * User1 adds user2 as follower. + */ + protected void user1AddsUser2AsFollower() + { + twitter.createEntityManager(); + twitter.addFollower(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * Gets the all tweets. + * + * @return the all tweets + */ + protected void getAllTweets() + { + twitter.createEntityManager(); + + List tweetsUser1 = twitter.getAllTweets(userId1); + List tweetsUser2 = twitter.getAllTweets(userId2); + + twitter.closeEntityManager(); + + Assert.assertNotNull(tweetsUser1); + Assert.assertNotNull(tweetsUser2); + + Assert.assertFalse(tweetsUser1.isEmpty()); + Assert.assertFalse(tweetsUser2.isEmpty()); + + Assert.assertEquals(3, tweetsUser1.size()); + Assert.assertEquals(2, tweetsUser2.size()); + } + + public void getPersonalDetailByName() + { + twitter.createEntityManager(); + List users = twitter.findPersonalDetailByName("Saurabh"); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + + UserCassandra user = users.get(0); + Assert.assertNotNull(user); + PersonalDetailCassandra pd = user.getPersonalDetail(); + Assert.assertNotNull(pd); + Assert.assertTrue(pd.getPersonalDetailId() != null && !pd.getPersonalDetailId().trim().equals("")); + Assert.assertTrue("Saurabh", pd.getName() != null); + Assert.assertEquals("password2", pd.getPassword()); + Assert.assertEquals("single", pd.getRelationshipStatus()); + + twitter.closeEntityManager(); + } + + /** + * Gets the tweets by body. + * + * @return the tweets by body + */ + public void getTweetsByBody() + { + twitter.createEntityManager(); + List user1Tweet = twitter.findTweetByBody("Here"); + List user2Tweet = twitter.findTweetByBody("Saurabh"); + + twitter.closeEntityManager(); + + Assert.assertNotNull(user1Tweet); + Assert.assertNotNull(user2Tweet); + Assert.assertEquals(1, user1Tweet.size()); + Assert.assertEquals(1, user2Tweet.size()); + } + + /** + * Gets the tweet by device. + * + * @return the tweet by device + */ + public void getTweetsByDevice() + { + twitter.createEntityManager(); + List webTweets = twitter.findTweetByDevice("Web"); + List mobileTweets = twitter.findTweetByDevice("Mobile"); + + twitter.closeEntityManager(); + + Assert.assertNotNull(webTweets); + Assert.assertNotNull(mobileTweets); + Assert.assertEquals(1, webTweets.size()); + Assert.assertEquals(1, mobileTweets.size()); + } + + public void getTweetsByRelationshipAndDevice() + { + // Positive scenario, record exists for user who is married and tweeted + // from Web + twitter.createEntityManager(); + List users = twitter.findByRelationshipAndDevice("married", "Web"); + twitter.closeEntityManager(); + + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertTrue(users.size() == 1); + UserCassandra user = users.get(0); + + Assert.assertFalse(user == null); + Assert.assertEquals("0001", user.getUserId()); + List tweets = user.getTweets(); + Assert.assertFalse(tweets == null); + Assert.assertTrue(tweets.size() == 1); + TweetCassandra tweet = tweets.get(0); + Assert.assertNotNull(tweet); + Assert.assertEquals("Web", tweet.getDevice()); + + // Negative scenario, record doesn't exist for user who is single and + // tweeted from mobile + twitter.createEntityManager(); + List users2 = twitter.findByRelationshipAndDevice("single", "Mobile"); + twitter.closeEntityManager(); + Assert.assertTrue(users2 == null || users2.isEmpty()); + } + + public void getTweetsByUserIdAndDevice() + { + // Positive scenario, record exists for user1 who tweeted from Web + twitter.createEntityManager(); + UserCassandra user = twitter.findByUserIdAndTweetDevice(userId1, "Web"); + twitter.closeEntityManager(); + Assert.assertNotNull(user); + Assert.assertEquals(userId1, user.getUserId()); + List tweets = user.getTweets(); + Assert.assertNotNull(tweets); + Assert.assertFalse(tweets.isEmpty()); + Assert.assertTrue(tweets.size() == 1); + Assert.assertEquals("Web", tweets.get(0).getDevice()); + + // Negative scenario, User 2 never tweeted from Mobile + twitter.createEntityManager(); + UserCassandra user2 = twitter.findByUserIdAndTweetDevice(userId2, "Mobile"); + twitter.closeEntityManager(); + Assert.assertNull(user2); + } + + /** + * Gets the all followers. + * + * @return the all followers + */ + protected void getAllFollowers() + { + twitter.createEntityManager(); + List follower1 = twitter.getFollowers(userId1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List follower2 = twitter.getFollowers(userId2); + twitter.closeEntityManager(); + + Assert.assertNull(follower1); + Assert.assertNotNull(follower2); + } + + /** + * @return + */ + private UserCassandra buildUser1() + { + UserCassandra user1 = new UserCassandra(userId1, "Amresh", "password1", "married"); + + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(1344079067777l)); + user1.setProfessionalDetail(new ProfessionalDetailCassandra(1234567, "Labs", false, 31, 'C', (byte) 8, + (short) 5, (float) 10.0, 163.12, new Date(Long.parseLong("1344079065781")), new Date(Long + .parseLong("1344079067623")), new Date(Long.parseLong("1344079069105")), 2, new Long( + 3634521523423L), new Double(0.23452342343), new java.sql.Date(new Date(Long + .parseLong("1344079061111")).getTime()), new java.sql.Time(new Date(Long + .parseLong("1344079062222")).getTime()), new java.sql.Timestamp(new Date(Long + .parseLong("13440790653333")).getTime()), new BigInteger("123456789"), + new BigDecimal(123456789), cal)); + + user1.setPreference(new PreferenceCassandra("P1", "Motif", "2")); + + user1.addExternalLink(new ExternalLinkCassandra("L1", "Facebook", "http://facebook.com/coolnerd")); + user1.addExternalLink(new ExternalLinkCassandra("L2", "LinkedIn", "http://linkedin.com/in/devilmate")); + + user1.addTweet(new TweetCassandra("Here is my first tweet", "Web")); + user1.addTweet(new TweetCassandra("Second Tweet from me", "Mobile")); + return user1; + } + + /** + * @return + */ + private UserCassandra buildUser2() + { + UserCassandra user2 = new UserCassandra(userId2, "Saurabh", "password2", "single"); + + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date(1344079068888l)); + user2.setProfessionalDetail(new ProfessionalDetailCassandra(1234568, "ODC", true, 32, 'A', (byte) 10, + (short) 8, (float) 9.80, 323.3, new Date(Long.parseLong("1344079063412")), new Date(Long + .parseLong("1344079068266")), new Date(Long.parseLong("1344079061078")), 5, new Long( + 25423452343L), new Double(0.76452343), new java.sql.Date(new Date(Long + .parseLong("1344079064444")).getTime()), new java.sql.Time(new Date(Long + .parseLong("1344079065555")).getTime()), new java.sql.Timestamp(new Date(Long + .parseLong("1344079066666")).getTime()), new BigInteger("123456790"), + new BigDecimal(123456790), cal)); + + user2.setPreference(new PreferenceCassandra("P2", "High Contrast", "3")); + + user2.addExternalLink(new ExternalLinkCassandra("L3", "GooglePlus", "http://plus.google.com/inviteme")); + user2.addExternalLink(new ExternalLinkCassandra("L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry")); + + user2.addTweet(new TweetCassandra("Saurabh tweets for the first time", "Phone")); + user2.addTweet(new TweetCassandra("Another tweet from Saurabh", "text")); + return user2; + } + + private void assertUser1(UserCassandra user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Amresh", user1.getPersonalDetail().getName()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(2, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + private void assertUser2(UserCassandra user2) + { + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + Assert.assertNotNull(user2.getPersonalDetail()); + Assert.assertEquals("Saurabh", user2.getPersonalDetail().getName()); + Assert.assertNotNull(user2.getPreference()); + Assert.assertEquals("3", user2.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user2.getTweets()); + Assert.assertFalse(user2.getTweets().isEmpty()); + Assert.assertEquals(2, user2.getTweets().size()); + Assert.assertNotNull(user2.getExternalLinks()); + Assert.assertFalse(user2.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user2.getExternalLinks().size()); + } + + private void assertUpdatedUser1(UserCassandra user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Vivek", user1.getPersonalDetail().getName()); + Assert.assertEquals("unknown", user1.getPersonalDetail().getPassword()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(3, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + abstract void startServer(); + + abstract void stopServer(); + + abstract void deleteSchema(); + + abstract void createSchema() throws NotFoundException, InvalidRequestException, TException, + SchemaDisagreementException; + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/SuperDaoCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/SuperDaoCassandra.java new file mode 100644 index 000000000..ac2b481d4 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/SuperDaoCassandra.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +/** + * The Class SuperDao. + * + * @author impetus + */ +public class SuperDaoCassandra +{ + + /** + * Inits the. + * + * @param persistenceUnitName + * the persistence unit name + * @return the entity manager + * @throws Exception + * the exception + */ + protected EntityManagerFactory createEntityManagerFactory(String persistenceUnitName) + { + return Persistence.createEntityManagerFactory(persistenceUnitName); + + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterCassandra.java new file mode 100644 index 000000000..9445d1c72 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterCassandra.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import com.impetus.client.twitter.entities.PreferenceCassandra; +import com.impetus.client.twitter.entities.TweetCassandra; +import com.impetus.client.twitter.entities.UserCassandra; + +/** + * Single window application for Twitter application. Contains methods for + * performing CRUD operations on users and their tweets. + */ +public interface TwitterCassandra +{ + + void addUser(UserCassandra user); + + /** + * Registers a new user with Twitter application + * + * @param userId + * the user id + * @param name + * the name + * @param password + * the password + * @param relationshipStatus + * the relationship status + */ + void addUser(String userId, String name, String password, String relationshipStatus); + + /** + * Save preference for a given user + * + * @param userId + * the user id + * @param preference + * the preference + */ + void savePreference(String userId, PreferenceCassandra preference); + + /** + * Adds an external link for the given user + * + * @param userId + * the user id + * @param linkType + * the link type + * @param linkAddress + * the link address + */ + void addExternalLink(String userId, String linkId, String linkType, String linkAddress); + + /** + * Adds a new tweet for a user + * + * @param userId + * the user id + * @param tweetBody + * the tweet body + * @param device + * the device + */ + void addTweet(String userId, String tweetBody, String device); + + /** + * Makes User whose row key is userId follow a user whose row + * key is friendUserId + * + * @param userId + * the user id + * @param friendUserId + * the friend user id + */ + void startFollowing(String userId, String friendUserId); + + /** + * Adds the follower whose row key is followerUserId to User + * whose row key is userId + * + * @param userId + * the user id + * @param followerUserId + * the follower user id + */ + void addFollower(String userId, String followerUserId); + + UserCassandra findUserById(String userId); + + void removeUser(UserCassandra user); + + void mergeUser(UserCassandra user); + + /** + * Retrieves all tweets for a given user + * + * @param userId + * the user id + * @return the all tweets + */ + List getAllUsers(); + + List getAllTweets(String userId); + + /** + * Returns a list of followers for a given user. + * + * @param userId + * user id + * @return list of all followers. + */ + List getFollowers(String userId); + + /************** Queries ***********************/ + + List findPersonalDetailByName(String name); + + /** + * Find tweets tweeted by individual with certain marital status and using a + * certain device. + * + * @param relationship + * @param device + * @return + */ + List findByRelationshipAndDevice(String relationship, String device); + + /** + * Get me all tweets that I tweeted from a particular device + * + * @param userId + * @param device + * @return + */ + UserCassandra findByUserIdAndTweetDevice(String userId, String device); + + /** + * Find tweet by tweet body. + * + * @param tweetBody + * the tweet body + * @return the list + */ + List findTweetByBody(String tweetBody); + + /** + * Find tweet by device. + * + * @param deviceName + * the device name + * @return the list + */ + List findTweetByDevice(String deviceName); + + /** + * Close. + */ + void close(); + + void createEntityManager(); + + void closeEntityManager(); + + /************** Queries on Professional Data ****************/ + List findUserByProfessionId(long professionId); + + List findUserByDepartment(String departmentName); + + List findExceptionalUsers(); + + List findUserByAge(int age); + + List findUserByGrade(char grade); + + List findUserByDigitalSignature(byte digitalSignature); + + List findUserByRating(short rating); + + List findUserByCompliance(float compliance); + + List findUserByHeight(double age); + + List findUserByEnrolmentDate(Date enrolmentDate); + + List findUserByEnrolmentTime(Date enrolmentTime); + + List findUserByJoiningDateAndTime(Date joiningDateAndTime); + + List findUserByYearsSpent(Integer yearsSpent); + + List findUserByUniqueId(Long uniqueId); + + List findUserByMonthlySalary(Double monthlySalary); + + List findUserByBirthday(java.sql.Date birthday); + + List findUserByBirthtime(java.sql.Time birthtime); + + List findUserByAnniversary(java.sql.Timestamp anniversary); + + List findUserByJobAttempts(BigInteger jobAttempts); + + List findUserByAccumulatedWealth(BigDecimal accumulatedWealth); + + List findUserByGraduationDay(Calendar graduationDay); +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterServiceCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterServiceCassandra.java new file mode 100644 index 000000000..954a55db9 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/dao/TwitterServiceCassandra.java @@ -0,0 +1,501 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Query; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.twitter.entities.ExternalLinkCassandra; +import com.impetus.client.twitter.entities.PreferenceCassandra; +import com.impetus.client.twitter.entities.TweetCassandra; +import com.impetus.client.twitter.entities.UserCassandra; +import com.impetus.kundera.KunderaException; + +/** + * Data access object class for implementation of twitter. + * + * @author amresh.singh + */ +public class TwitterServiceCassandra extends SuperDaoCassandra implements TwitterCassandra +{ + private static final Logger log = LoggerFactory.getLogger(TwitterServiceCassandra.class); + + private EntityManager em; + + private EntityManagerFactory emf; + + public TwitterServiceCassandra(String persistenceUnitName) + { + if (emf == null) + { + try + { + emf = createEntityManagerFactory(persistenceUnitName); + } + catch (Exception e) + { + log.error(e.getMessage(),e); + throw new KunderaException(e); + } + } + + } + + @Override + public void createEntityManager() + { + if (em == null) + { + em = emf.createEntityManager(); + } + } + + @Override + public void closeEntityManager() + { + if (em != null) + { + em.close(); + em = null; + } + } + + @Override + public void close() + { + if (emf != null) + { + emf.close(); + } + } + + @Override + public void addUser(UserCassandra user) + { + em.persist(user); + } + + @Override + public void addUser(String userId, String name, String password, String relationshipStatus) + { + UserCassandra user = new UserCassandra(userId, name, password, relationshipStatus); + em.persist(user); + + } + + @Override + public void savePreference(String userId, PreferenceCassandra preference) + { + + UserCassandra user = em.find(UserCassandra.class, userId); + user.setPreference(preference); + em.persist(user); + } + + @Override + public void addExternalLink(String userId, String linkId, String linkType, String linkAddress) + { + UserCassandra user = em.find(UserCassandra.class, userId); + user.addExternalLink(new ExternalLinkCassandra(linkId, linkType, linkAddress)); + + em.persist(user); + } + + @Override + public void addTweet(String userId, String tweetBody, String device) + { + UserCassandra user = em.find(UserCassandra.class, userId); + user.addTweet(new TweetCassandra(tweetBody, device)); + em.persist(user); + } + + @Override + public void startFollowing(String userId, String friendUserId) + { + UserCassandra user = em.find(UserCassandra.class, userId); + UserCassandra friend = em.find(UserCassandra.class, friendUserId); + + user.addFriend(friend); + em.persist(user); + + friend.addFollower(user); + em.persist(friend); + } + + @Override + public void addFollower(String userId, String followerUserId) + { + UserCassandra user = em.find(UserCassandra.class, userId); + UserCassandra follower = em.find(UserCassandra.class, followerUserId); + + user.addFollower(follower); + em.persist(user); + } + + @Override + public UserCassandra findUserById(String userId) + { + em.clear(); + UserCassandra user = em.find(UserCassandra.class, userId); + return user; + } + + @Override + public void removeUser(UserCassandra user) + { + em.remove(user); + } + + @Override + public void mergeUser(UserCassandra user) + { + em.merge(user); + } + + @Override + public List getAllUsers() + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u"); + + List users = q.getResultList(); + + return users; + } + + @Override + public List getAllTweets(String userId) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + else + { + return users.get(0).getTweets(); + } + } + + @Override + public List getFollowers(String userId) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + return users.get(0).getFollowers(); + } + + @Override + public List findPersonalDetailByName(String name) + { + em.clear(); + Query q = em + .createQuery("select u.personalDetail.name from UserCassandra u where u.personalDetail.name =:name"); + q.setParameter("name", name); + List users = q.getResultList(); + return users; + } + + @Override + public List findTweetByBody(String tweetBody) + { + em.clear(); + Query q = em.createQuery("select u.tweets.body from UserCassandra u where u.tweets.body like :body"); + q.setParameter("body", tweetBody); + List tweets = q.getResultList(); + return tweets; + } + + @Override + public List findTweetByDevice(String deviceName) + { + em.clear(); + Query q = em.createQuery("select u.tweets.device from UserCassandra u where u.tweets.device =:device"); + q.setParameter("device", deviceName); + List tweets = q.getResultList(); + return tweets; + } + + @Override + public List findByRelationshipAndDevice(String relationship, String device) + { + em.clear(); + Query q = em + .createQuery("select u.tweets.device from UserCassandra u where u.tweets.device=:device and u.personalDetail.relationshipStatus=:relation"); + q.setParameter("device", device); + q.setParameter("relation", relationship); + List users = q.getResultList(); + return users; + } + + @Override + public UserCassandra findByUserIdAndTweetDevice(String userId, String device) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.tweets.device=:device and u.userId=:userId"); + q.setParameter("device", device); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users != null && !users.isEmpty()) + { + return users.get(0); + } + return null; + } + + /************* Queries on Professional Details for all data types *************/ + @Override + public List findUserByProfessionId(long professionId) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.professionId =:professionId"); + q.setParameter("professionId", professionId); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByDepartment(String departmentName) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.departmentName =:departmentName"); + q.setParameter("departmentName", departmentName); + List users = q.getResultList(); + return users; + } + + @Override + public List findExceptionalUsers() + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.isExceptional =:isExceptional"); + q.setParameter("isExceptional", true); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByAge(int age) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.age =:age"); + q.setParameter("age", age); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByGrade(char grade) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.grade =:grade"); + q.setParameter("grade", grade); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByDigitalSignature(byte digitalSignature) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.digitalSignature =:digitalSignature"); + q.setParameter("digitalSignature", digitalSignature); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByRating(short rating) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.rating =:rating"); + q.setParameter("rating", rating); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByCompliance(float compliance) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.compliance =:compliance"); + q.setParameter("compliance", compliance); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByHeight(double height) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.height =:height"); + q.setParameter("height", height); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByEnrolmentDate(Date enrolmentDate) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.enrolmentDate =:enrolmentDate"); + q.setParameter("enrolmentDate", enrolmentDate); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByEnrolmentTime(Date enrolmentTime) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.enrolmentTime =:enrolmentTime"); + q.setParameter("enrolmentTime", enrolmentTime); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByJoiningDateAndTime(Date joiningDateAndTime) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.joiningDateAndTime =:joiningDateAndTime"); + q.setParameter("joiningDateAndTime", joiningDateAndTime); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByYearsSpent(Integer yearsSpent) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.yearsSpent =:yearsSpent"); + q.setParameter("yearsSpent", yearsSpent); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByUniqueId(Long uniqueId) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.uniqueId =:uniqueId"); + q.setParameter("uniqueId", uniqueId); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByMonthlySalary(Double monthlySalary) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.monthlySalary =:monthlySalary"); + q.setParameter("monthlySalary", monthlySalary); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByBirthday(java.sql.Date birthday) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.birthday =:birthday"); + q.setParameter("birthday", birthday); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByBirthtime(Time birthtime) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.birthtime =:birthtime"); + q.setParameter("birthtime", birthtime); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByAnniversary(Timestamp anniversary) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.anniversary =:anniversary"); + q.setParameter("anniversary", anniversary); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByJobAttempts(BigInteger jobAttempts) + { + em.clear(); + Query q = em.createQuery("select u from UserCassandra u where u.professionalDetail.jobAttempts =:jobAttempts"); + q.setParameter("jobAttempts", jobAttempts); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByAccumulatedWealth(BigDecimal accumulatedWealth) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.accumulatedWealth =:accumulatedWealth"); + q.setParameter("accumulatedWealth", accumulatedWealth); + List users = q.getResultList(); + return users; + } + + @Override + public List findUserByGraduationDay(Calendar graduationDay) + { + em.clear(); + Query q = em + .createQuery("select u from UserCassandra u where u.professionalDetail.graduationDay =:graduationDay"); + q.setParameter("graduationDay", graduationDay); + List users = q.getResultList(); + return users; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ExternalLinkCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ExternalLinkCassandra.java new file mode 100644 index 000000000..7c4493b86 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ExternalLinkCassandra.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for user's External link details + * + * @author amresh.singh + */ + +@Entity +@Table(name = "EXTERNAL_LINK", schema = "KunderaExamples@twissandraTest") +public class ExternalLinkCassandra +{ + + @Id + @Column(name = "EXT_LINK_ID") + private String extLinkId; + + @Column(name = "LINK_TYPE") + private String linkType; + + @Column(name = "LINK_ADDRESS") + private String linkAddress; + + public ExternalLinkCassandra() + { + } + + public ExternalLinkCassandra(String extLinkId, String type, String address) + { + this.extLinkId = extLinkId; + this.linkType = type; + this.linkAddress = address; + } + + /** + * @return the extLinkId + */ + public String getExtLinkId() + { + return extLinkId; + } + + /** + * @param extLinkId + * the extLinkId to set + */ + public void setExtLinkId(String extLinkId) + { + this.extLinkId = extLinkId; + } + + /** + * @return the linkType + */ + public String getLinkType() + { + return linkType; + } + + /** + * @param linkType + * the linkType to set + */ + public void setLinkType(String linkType) + { + this.linkType = linkType; + } + + /** + * @return the linkAddress + */ + public String getLinkAddress() + { + return linkAddress; + } + + /** + * @param linkAddress + * the linkAddress to set + */ + public void setLinkAddress(String linkAddress) + { + this.linkAddress = linkAddress; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PersonalDetailCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PersonalDetailCassandra.java new file mode 100644 index 000000000..157fba9a8 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PersonalDetailCassandra.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsCassandra; +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Entity class for user's personal details + * + * @author amresh.singh + */ + +@Embeddable +@IndexCollection(columns = { @Index(name = "name"), @Index(name = "relationshipStatus") }) +public class PersonalDetailCassandra +{ + @Column(name = "personal_detail_id") + private String personalDetailId; + + @Column(name = "person_name") + private String name; + + @Column(name = "person_password") + private String password; + + @Column(name = "rel_status") + private String relationshipStatus; + + public PersonalDetailCassandra() + { + + } + + public PersonalDetailCassandra(String name, String password, String relationshipStatus) + { + setPersonalDetailId(ExampleUtilsCassandra.getUniqueId()); + setName(name); + setPassword(password); + setRelationshipStatus(relationshipStatus); + } + + /** + * @return the personalDetailId + */ + public String getPersonalDetailId() + { + return personalDetailId; + } + + /** + * @param personalDetailId + * the personalDetailId to set + */ + public void setPersonalDetailId(String personalDetailId) + { + this.personalDetailId = personalDetailId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the password + */ + public String getPassword() + { + return password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * @return the relationshipStatus + */ + public String getRelationshipStatus() + { + return relationshipStatus; + } + + /** + * @param relationshipStatus + * the relationshipStatus to set + */ + public void setRelationshipStatus(String relationshipStatus) + { + this.relationshipStatus = relationshipStatus; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PreferenceCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PreferenceCassandra.java new file mode 100644 index 000000000..8f114d1ba --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/PreferenceCassandra.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for User Preferences + * + * @author amresh.singh + */ + +@Entity +@Table(name = "PREFERENCE", schema = "KunderaExamples@twissandraTest") +public class PreferenceCassandra +{ + @Id + @Column(name = "PREFERENCE_ID") + String preferenceId; + + @Column(name = "WEBSITE_THEME") + String websiteTheme; + + @Column(name = "PRIVACY_LEVEL") + String privacyLevel; // 1, 2, 3 + + public PreferenceCassandra() + { + + } + + public PreferenceCassandra(String preferenceId, String theme, String privacyLevel) + { + this.preferenceId = preferenceId; + this.websiteTheme = theme; + this.privacyLevel = privacyLevel; + } + + /** + * @return the preferenceId + */ + public String getPreferenceId() + { + return preferenceId; + } + + /** + * @param preferenceId + * the preferenceId to set + */ + public void setPreferenceId(String preferenceId) + { + this.preferenceId = preferenceId; + } + + /** + * @return the websiteTheme + */ + public String getWebsiteTheme() + { + return websiteTheme; + } + + /** + * @param websiteTheme + * the websiteTheme to set + */ + public void setWebsiteTheme(String websiteTheme) + { + this.websiteTheme = websiteTheme; + } + + /** + * @return the privacyLevel + */ + public String getPrivacyLevel() + { + return privacyLevel; + } + + /** + * @param privacyLevel + * the privacyLevel to set + */ + public void setPrivacyLevel(String privacyLevel) + { + this.privacyLevel = privacyLevel; + } +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ProfessionalDetailCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ProfessionalDetailCassandra.java new file mode 100644 index 000000000..ff8c24057 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/ProfessionalDetailCassandra.java @@ -0,0 +1,511 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.twitter.entities; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Holds professional details of any user + * + * @author amresh.singh + */ + +@Embeddable +@IndexCollection(columns = { @Index(name = "professionId"), @Index(name = "departmentName"), + @Index(name = "isExceptional"), @Index(name = "age"), @Index(name = "grade"), + @Index(name = "digitalSignature"), @Index(name = "rating"), @Index(name = "compliance"), + @Index(name = "height"), @Index(name = "enrolmentDate"), @Index(name = "enrolmentTime"), + @Index(name = "joiningDateAndTime"), @Index(name = "yearsSpent"), @Index(name = "uniqueId"), + @Index(name = "monthlySalary"), @Index(name = "birthday"), @Index(name = "birthtime"), + @Index(name = "anniversary"), @Index(name = "jobAttempts"), @Index(name = "accumulatedWealth"), + @Index(name = "graduationDay") }) +public class ProfessionalDetailCassandra +{ + // Primitive Types + @Column(name = "PROFESSION_ID") + private long professionId; + + @Column(name = "DEPARTMENT_NAME") + private String departmentName; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "AGE") + private int age; + + @Column(name = "GRADE") + private char grade; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "RATING") + private short rating; // 1-10 + + @Column(name = "COMPLIANCE") + private float compliance; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "UNIQUE_ID") + private Long uniqueId; + + @Column(name = "MONTHLY_SALARY") + private Double monthlySalary; + + @Column(name = "BIRTH_DAY") + private java.sql.Date birthday; + + @Column(name = "BIRTH_TIME") + private java.sql.Time birthtime; + + @Column(name = "ANNIVERSARY") + private java.sql.Timestamp anniversary; + + @Column(name = "JOB_ATTEMPTS") + private BigInteger jobAttempts; + + @Column(name = "ACCUMULATED_WEALTH") + private BigDecimal accumulatedWealth; + + @Column(name = "GRADUATION_DAY") + private Calendar graduationDay; + + public ProfessionalDetailCassandra(long professionId, String departmentName, boolean isExceptional, int age, + char grade, byte digitalSignature, short rating, float compliance, double height, Date enrolmentDate, + Date enrolmentTime, Date joiningDateAndTime, Integer yearsSpent, Long uniqueId, Double monthlySalary, + java.sql.Date birthday, Time birthtime, Timestamp anniversary, BigInteger jobAttempts, + BigDecimal accumulatedWealth, Calendar graduationDay) + { + super(); + this.professionId = professionId; + this.departmentName = departmentName; + this.isExceptional = isExceptional; + this.age = age; + this.grade = grade; + this.digitalSignature = digitalSignature; + this.rating = rating; + this.compliance = compliance; + this.height = height; + this.enrolmentDate = enrolmentDate; + this.enrolmentTime = enrolmentTime; + this.joiningDateAndTime = joiningDateAndTime; + this.yearsSpent = yearsSpent; + this.uniqueId = uniqueId; + this.monthlySalary = monthlySalary; + this.birthday = birthday; + this.birthtime = birthtime; + this.anniversary = anniversary; + this.jobAttempts = jobAttempts; + this.accumulatedWealth = accumulatedWealth; + this.graduationDay = graduationDay; + } + + public ProfessionalDetailCassandra() + { + + } + + /** + * @return the professionId + */ + public long getProfessionId() + { + return professionId; + } + + /** + * @param professionId + * the professionId to set + */ + public void setProfessionId(long professionId) + { + this.professionId = professionId; + } + + /** + * @return the departmentName + */ + public String getDepartmentName() + { + return departmentName; + } + + /** + * @param departmentName + * the departmentName to set + */ + public void setDepartmentName(String departmentName) + { + this.departmentName = departmentName; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the grade + */ + public char getGrade() + { + return grade; + } + + /** + * @param grade + * the grade to set + */ + public void setGrade(char grade) + { + this.grade = grade; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the rating + */ + public short getRating() + { + return rating; + } + + /** + * @param rating + * the rating to set + */ + public void setRating(short rating) + { + this.rating = rating; + } + + /** + * @return the compliance + */ + public float getCompliance() + { + return compliance; + } + + /** + * @param compliance + * the compliance to set + */ + public void setCompliance(float compliance) + { + this.compliance = compliance; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the uniqueId + */ + public Long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(Long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the monthlySalary + */ + public Double getMonthlySalary() + { + return monthlySalary; + } + + /** + * @param monthlySalary + * the monthlySalary to set + */ + public void setMonthlySalary(Double monthlySalary) + { + this.monthlySalary = monthlySalary; + } + + /** + * @return the birthday + */ + public java.sql.Date getBirthday() + { + return birthday; + } + + /** + * @param birthday + * the birthday to set + */ + public void setBirthday(java.sql.Date birthday) + { + this.birthday = birthday; + } + + /** + * @return the birthtime + */ + public java.sql.Time getBirthtime() + { + return birthtime; + } + + /** + * @param birthtime + * the birthtime to set + */ + public void setBirthtime(java.sql.Time birthtime) + { + this.birthtime = birthtime; + } + + /** + * @return the anniversary + */ + public java.sql.Timestamp getAnniversary() + { + return anniversary; + } + + /** + * @param anniversary + * the anniversary to set + */ + public void setAnniversary(java.sql.Timestamp anniversary) + { + this.anniversary = anniversary; + } + + /** + * @return the jobAttempts + */ + public BigInteger getJobAttempts() + { + return jobAttempts; + } + + /** + * @param jobAttempts + * the jobAttempts to set + */ + public void setJobAttempts(BigInteger jobAttempts) + { + this.jobAttempts = jobAttempts; + } + + /** + * @return the accumulatedWealth + */ + public BigDecimal getAccumulatedWealth() + { + return accumulatedWealth; + } + + /** + * @param accumulatedWealth + * the accumulatedWealth to set + */ + public void setAccumulatedWealth(BigDecimal accumulatedWealth) + { + this.accumulatedWealth = accumulatedWealth; + } + + /** + * @return the graduationDay + */ + public Calendar getGraduationDay() + { + return graduationDay; + } + + /** + * @param graduationDay + * the graduationDay to set + */ + public void setGraduationDay(Calendar graduationDay) + { + this.graduationDay = graduationDay; + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/TweetCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/TweetCassandra.java new file mode 100644 index 000000000..f32c9de2e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/TweetCassandra.java @@ -0,0 +1,123 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsCassandra; +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Class for Tweets + * + * @author amresh.singh + */ + +@Embeddable +@IndexCollection(columns = { @Index(name = "body"), @Index(name = "device") }) +public class TweetCassandra +{ + + @Column(name = "tweet_id") + private String tweetId; + + @Column(name = "tweet_body") + private String body; + + @Column(name = "tweeted_from") + private String device; + + // private long timestamp; + + public TweetCassandra(String body, String device) + { + this.tweetId = ExampleUtilsCassandra.getUniqueId(); + this.body = body; + this.device = device; + // this.timestamp = ExampleUtils.getCurrentTimestamp(); + } + + public TweetCassandra() + { + + } + + /** + * @return the tweetId + */ + public String getTweetId() + { + return tweetId; + } + + /** + * @param tweetId + * the tweetId to set + */ + public void setTweetId(String tweetId) + { + this.tweetId = tweetId; + } + + /** + * @return the body + */ + public String getBody() + { + return body; + } + + /** + * @param body + * the body to set + */ + public void setBody(String body) + { + this.body = body; + } + + /** + * @return the device + */ + public String getDevice() + { + return device; + } + + /** + * @param device + * the device to set + */ + public void setDevice(String device) + { + this.device = device; + } + + /* *//** + * @return the timestamp + */ + /* + * public long getTimestamp() { return timestamp; } + *//** + * @param timestamp + * the timestamp to set + */ + /* + * public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + */ +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/UserCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/UserCassandra.java new file mode 100644 index 000000000..d4b838711 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/entities/UserCassandra.java @@ -0,0 +1,248 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * @author impetus + * + */ +@Entity +@Table(name = "USER", schema = "KunderaExamples@twissandraTest") +public class UserCassandra +{ + + @Id + @Column(name = "USER_ID") + private String userId; + + // Embedded object, will persist co-located + @Embedded + private PersonalDetailCassandra personalDetail; + + // Embedded object, will persist co-located + @Embedded + private ProfessionalDetailCassandra professionalDetail; + + // Element collection, will persist co-located + @ElementCollection + @CollectionTable(name = "tweeted") + private List tweets; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FRIEND_ID") + private List friends; // List of users whom I follow + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FOLLOWER_ID") + private List followers; // List of users who are following me + + // One-to-one, will be persisted separately + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) + @JoinColumn(name = "PREFERENCE_ID") + private PreferenceCassandra preference; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY) + @JoinColumn(name = "USER_ID") + private Set externalLinks; + + public UserCassandra() + { + + } + + public UserCassandra(String userId, String name, String password, String relationshipStatus) + { + PersonalDetailCassandra pd = new PersonalDetailCassandra(name, password, relationshipStatus); + setUserId(userId); + setPersonalDetail(pd); + } + + /** + * @return the userId + */ + public String getUserId() + { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(String userId) + { + this.userId = userId; + } + + /** + * @return the personalDetail + */ + public PersonalDetailCassandra getPersonalDetail() + { + return personalDetail; + } + + /** + * @param personalDetail + * the personalDetail to set + */ + public void setPersonalDetail(PersonalDetailCassandra personalDetail) + { + this.personalDetail = personalDetail; + } + + /** + * @return the professionalDetail + */ + public ProfessionalDetailCassandra getProfessionalDetail() + { + return professionalDetail; + } + + /** + * @param professionalDetail + * the professionalDetail to set + */ + public void setProfessionalDetail(ProfessionalDetailCassandra professionalDetail) + { + this.professionalDetail = professionalDetail; + } + + /** + * @return the tweets + */ + public List getTweets() + { + return tweets; + } + + /** + * @param tweets + * the tweets to set + */ + public void addTweet(TweetCassandra tweet) + { + if (this.tweets == null || this.tweets.isEmpty()) + { + this.tweets = new ArrayList(); + } + this.tweets.add(tweet); + } + + /** + * @return the preference + */ + public PreferenceCassandra getPreference() + { + return preference; + } + + /** + * @param preference + * the preference to set + */ + public void setPreference(PreferenceCassandra preference) + { + this.preference = preference; + } + + /** + * @return the externalLinks + */ + public Set getExternalLinks() + { + return externalLinks; + } + + /** + * @param imDetails + * the imDetails to set + */ + public void addExternalLink(ExternalLinkCassandra externalLink) + { + if (this.externalLinks == null || this.externalLinks.isEmpty()) + { + this.externalLinks = new HashSet(); + } + + this.externalLinks.add(externalLink); + } + + /** + * @return the friends + */ + public List getFriends() + { + return friends; + } + + /** + * @param friends + * the friends to set + */ + public void addFriend(UserCassandra friend) + { + if (this.friends == null || this.friends.isEmpty()) + { + this.friends = new ArrayList(); + } + this.friends.add(friend); + } + + /** + * @return the followers + */ + public List getFollowers() + { + return followers; + } + + /** + * @param followers + * the followers to set + */ + public void addFollower(UserCassandra follower) + { + if (this.followers == null || this.followers.isEmpty()) + { + this.followers = new ArrayList(); + } + + this.followers.add(follower); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsCassandra.java b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsCassandra.java new file mode 100644 index 000000000..e03a5dd79 --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsCassandra.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.utils; + +import java.util.Date; +import java.util.UUID; + +/** + * Class for utility methods + * + * @author amresh.singh + */ +public class ExampleUtilsCassandra +{ + public static String getUniqueId() + { + return UUID.randomUUID().toString(); + } + + public static long getCurrentTimestamp() + { + return new Date().getTime(); + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/KunderaQueryTest.java b/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/KunderaQueryTest.java new file mode 100644 index 000000000..ade2c329a --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/KunderaQueryTest.java @@ -0,0 +1,271 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.query; + +import java.util.Iterator; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Parameter; +import javax.persistence.Persistence; +import javax.persistence.PersistenceException; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.entity.CassandraUUIDEntity; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.metadata.KunderaMetadataManager; + +/** + * @author kuldeep.mishra + * + */ +public class KunderaQueryTest +{ + + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace("UUIDCassandra"); + emf = Persistence.createEntityManagerFactory("cass_pu"); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + } + + @Test + public void test() + { + String query = "Select p from CassandraUUIDEntity p"; + KunderaQuery kunderaQuery = new KunderaQuery(); + KunderaQueryParser queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.assertNotNull(kunderaQuery.getEntityClass()); + Assert.assertEquals(CassandraUUIDEntity.class, kunderaQuery.getEntityClass()); + Assert.assertNotNull(kunderaQuery.getEntityMetadata()); + Assert.assertTrue(KunderaMetadataManager.getEntityMetadata(CassandraUUIDEntity.class).equals( + kunderaQuery.getEntityMetadata())); + Assert.assertNull(kunderaQuery.getFilter()); + Assert.assertTrue(kunderaQuery.getFilterClauseQueue().isEmpty()); + Assert.assertNotNull(kunderaQuery.getFrom()); + Assert.assertTrue(kunderaQuery.getUpdateClauseQueue().isEmpty()); + Assert.assertNotNull(kunderaQuery.getResult()); + Assert.assertEquals("cass_pu", kunderaQuery.getPersistenceUnit()); + Assert.assertNull(kunderaQuery.getOrdering()); + try + { + query = "Select p from p"; + kunderaQuery = new KunderaQuery(); + queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.fail(); + } + catch (JPQLParseException e) + { + Assert.assertEquals( + "Bad query format: p. Identification variable is mandatory in FROM clause for SELECT queries. For details, see: http://openjpa.apache.org/builds/1.0.4/apache-openjpa-1.0.4/docs/manual/jpa_langref.html#jpa_langref_bnf", + e.getMessage()); + } + try + { + query = "Select p form CassandraUUIDEntity p"; + kunderaQuery = new KunderaQuery(); + queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.fail(); + } + catch (JPQLParseException e) + { + Assert.assertEquals( + "Bad query format FROM clause is mandatory for SELECT queries. For details, see: http://openjpa.apache.org/builds/1.0.4/apache-openjpa-1.0.4/docs/manual/jpa_langref.html#jpa_langref_bnf", + e.getMessage()); + } + try + { + query = "Selct p from CassandraUUIDEntity p"; + kunderaQuery = new KunderaQuery(); + queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.assertNotNull(kunderaQuery.getEntityClass()); + Assert.assertEquals(CassandraUUIDEntity.class, kunderaQuery.getEntityClass()); + Assert.assertNotNull(kunderaQuery.getEntityMetadata()); + Assert.assertTrue(KunderaMetadataManager.getEntityMetadata(CassandraUUIDEntity.class).equals( + kunderaQuery.getEntityMetadata())); + Assert.assertNull(kunderaQuery.getFilter()); + Assert.assertTrue(kunderaQuery.getFilterClauseQueue().isEmpty()); + Assert.assertNotNull(kunderaQuery.getFrom()); + Assert.assertTrue(kunderaQuery.getUpdateClauseQueue().isEmpty()); + Assert.assertNotNull(kunderaQuery.getResult()); + Assert.assertEquals("cass_pu", kunderaQuery.getPersistenceUnit()); + Assert.assertNull(kunderaQuery.getOrdering()); + } + catch (JPQLParseException e) + { + Assert.fail(); + } + try + { + query = "Select p from CassandraUUIDEntity p where"; + kunderaQuery = new KunderaQuery(); + queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.fail(); + } + catch (JPQLParseException e) + { + Assert.assertEquals( + "keyword without value[WHERE]. For details, see: http://openjpa.apache.org/builds/1.0.4/apache-openjpa-1.0.4/docs/manual/jpa_langref.html#jpa_langref_bnf", + e.getMessage()); + } + try + { + query = "Select p from CassandraUUIDEntity p where p"; + kunderaQuery = new KunderaQuery(); + queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + Assert.fail(); + } + catch (PersistenceException e) + { + Assert.assertEquals("bad jpa query: p", e.getMessage()); + } + } + + @Test + public void testOnIndexParameter() + { + String query = "Select p from CassandraUUIDEntity p where p.uuidKey = ?1 and p.name= ?2"; + KunderaQuery kunderaQuery = new KunderaQuery(); + KunderaQueryParser queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + kunderaQuery.setParameter(1, "uuid1"); + kunderaQuery.setParameter(2, "uuidname"); + + Object value = kunderaQuery.getClauseValue("?1"); + Assert.assertNotNull(value); + Assert.assertEquals("uuid1", value); + value = kunderaQuery.getClauseValue("?2"); + Assert.assertNotNull(value); + Assert.assertEquals("uuidname", value); + Assert.assertEquals(2, kunderaQuery.getParameters().size()); + + Iterator> parameters = kunderaQuery.getParameters().iterator(); + + while(parameters.hasNext()) + { + Assert.assertTrue(kunderaQuery.isBound(parameters.next())); + } + } + + @Test + public void testOnNameParameter() + { + String query = "Select p from CassandraUUIDEntity p where p.uuidKey = :uuid and p.name= :name"; + KunderaQuery kunderaQuery = new KunderaQuery(); + KunderaQueryParser queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + kunderaQuery.setParameter("uuid", "uuid1"); + kunderaQuery.setParameter("name", "uuidname"); + + Assert.assertEquals(2, kunderaQuery.getParameters().size()); + + Iterator> parameters = kunderaQuery.getParameters().iterator(); + + while(parameters.hasNext()) + { + Assert.assertTrue(kunderaQuery.isBound(parameters.next())); + } + + Object value = kunderaQuery.getClauseValue(":uuid"); + Assert.assertNotNull(value); + Assert.assertEquals("uuid1", value); + value = kunderaQuery.getClauseValue(":name"); + Assert.assertNotNull(value); + Assert.assertEquals("uuidname", value); + Assert.assertEquals(2, kunderaQuery.getParameters().size()); + + } + + @Test + public void testInvalidIndexParameter() + { + String query = "Select p from CassandraUUIDEntity p where p.uuidKey = ?1 and p.name= ?2"; + KunderaQuery kunderaQuery = new KunderaQuery(); + KunderaQueryParser queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + kunderaQuery.setParameter(1, "uuid1"); + kunderaQuery.setParameter(2, "uuidname"); + + try + { + kunderaQuery.getClauseValue("?3"); + Assert.fail("Should be catch block"); + } catch(IllegalArgumentException iaex) + { + Assert.assertEquals("parameter is not a parameter of the query", iaex.getMessage()); + } + } + + @Test + public void testInvalidNameParameter() + { + String query = "Select p from CassandraUUIDEntity p where p.uuidKey = :uuid and p.name= :name"; + KunderaQuery kunderaQuery = new KunderaQuery(); + KunderaQueryParser queryParser = new KunderaQueryParser(kunderaQuery, query); + queryParser.parse(); + kunderaQuery.postParsingInit(); + kunderaQuery.setParameter("uuid", "uuid1"); + kunderaQuery.setParameter("name", "uuidname"); + + try + { + kunderaQuery.getClauseValue(":naame"); + Assert.fail("Should be catch block"); + } catch(IllegalArgumentException iaex) + { + Assert.assertEquals("parameter is not a parameter of the query", iaex.getMessage()); + } + } + +} diff --git a/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/ResultIteratorTest.java b/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/ResultIteratorTest.java new file mode 100644 index 000000000..1d9e3ae5e --- /dev/null +++ b/src/kundera-cassandra/src/test/java/com/impetus/kundera/query/ResultIteratorTest.java @@ -0,0 +1,245 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.query; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.Assert; +import org.junit.Test; + +import com.impetus.client.cassandra.common.CassandraConstants; +import com.impetus.client.crud.BaseTest; +import com.impetus.client.crud.PersonCassandra; +import com.impetus.client.crud.Token; +import com.impetus.client.crud.TokenClient; +import com.impetus.client.persistence.CassandraCli; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * @author vivek.mishra + * junit for {@link IResultIterator}. + */ +public class ResultIteratorTest extends BaseTest +{ + private static final String SEC_IDX_CASSANDRA_TEST = "secIdxCassandraTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + public void setUp(final String persistenceUnit,final String keyspace, final String cqlVersion) throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + CassandraCli.cassandraSetUp(); + CassandraCli.createKeySpace(keyspace); + Map propertyMap = new HashMap(); + propertyMap.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "create"); + propertyMap.put(CassandraConstants.CQL_VERSION, cqlVersion); + + emf = Persistence.createEntityManagerFactory(persistenceUnit, propertyMap); + em = emf.createEntityManager(); + } + + @Test + public void testScrollViaCQL3() throws Exception + { + setUp(SEC_IDX_CASSANDRA_TEST,"KunderaExamples",CassandraConstants.CQL_VERSION_3_0); + onScroll(); + tearDown("KunderaExamples"); + } + + @Test + public void testScrollViaCQL2() throws Exception + { + setUp(SEC_IDX_CASSANDRA_TEST,"KunderaExamples",CassandraConstants.CQL_VERSION_3_0); + onScroll(); + tearDown("KunderaExamples"); + } + + @Test + public void testCQL3ScrollAssociation() throws Exception + { + setUp("myapp_pu", "myapp", CassandraConstants.CQL_VERSION_3_0); + assertOnTokenScroll(); + tearDown("myapp"); + } + + @Test + public void testCQL2ScrollAssociation() throws Exception + { + setUp("myapp_pu", "myapp", CassandraConstants.CQL_VERSION_2_0); + assertOnTokenScroll(); + tearDown("myapp"); + } + + private void assertOnTokenScroll() + { + Token token1 = new Token(); + token1.setId("tokenId1"); + token1.setTokenName("tokenName1"); + TokenClient client = new TokenClient(); + client.setClientName("tokenClient1"); + client.setId("tokenClientId"); + token1.setClient(client); + + Token token2 = new Token(); + token2.setId("tokenId2"); + token2.setTokenName("tokenName2"); + token2.setClient(client); + em.persist(token1); + em.persist(token2); + + String queryWithoutClause = "Select t from Token t"; + assertOnTokenScroll(queryWithoutClause,2); + + + String queryWithClause = "Select t from Token t where t.tokenName='tokenName1'"; + + assertOnTokenScroll(queryWithClause,1); + + //TODO:: Need to discuss with KK, this should be working with token support. Special scenario. + String queryWithIdClause = "Select t from Token t where t.id = 'tokenId1'"; +// + assertOnTokenScroll(queryWithIdClause,1); + + + } + + private void assertOnTokenScroll(String queryClause, int expected) + { + Query query = (Query) em.createQuery(queryClause, + Token.class); + + int count=0; + Iterator tokens = query.iterate(); + while(tokens.hasNext()) + { + Token token = tokens.next(); + Assert.assertNotNull(token); + Assert.assertNotNull(token.getClient()); + Assert.assertEquals(2, token.getClient().getTokens().size()); + count++; + } + + Assert.assertTrue(count > 0); + Assert.assertTrue(count == expected); + } + + private void onScroll() + { + Object p1 = prepareData("1", 10); + Object p2 = prepareData("2", 20); + Object p3 = prepareData("3", 15); + + em.persist(p1); + em.persist(p2); + em.persist(p3); + + em.flush(); + em.clear(); + final String queryWithoutClause = "Select p from PersonCassandra p"; + + assertOnScroll(queryWithoutClause,3); + + final String queryWithClause = "Select p from PersonCassandra p where p.personName = vivek"; + + assertOnScroll(queryWithClause,3); + + final String queryWithAndClause = "Select p from PersonCassandra p where p.personName = vivek and p.age = 15"; + + assertOnScroll(queryWithAndClause,1); + + final String queryWithLTClause = "Select p from PersonCassandra p where p.personName = vivek and p.age < 15"; + + assertOnScroll(queryWithLTClause,1); + + final String queryWithGTClause = "Select p from PersonCassandra p where p.personName = vivek and p.age >= 15"; + + assertOnScroll(queryWithGTClause,2); + + final String queryWithLTGTClause = "Select p from PersonCassandra p where p.personName = vivek and p.age > 10 and p.age < 20"; + + assertOnScroll(queryWithLTGTClause,1); + + final String queryWithLTGTEClause = "Select p from PersonCassandra p where p.personName = vivek and p.age >= 10 and p.age < 20"; + + assertOnScroll(queryWithLTGTEClause,2); + + String queryWithIdClause = "Select p from PersonCassandra p where p.personId = '2' "; + assertOnScroll(queryWithIdClause,1); + } + + private void assertOnScroll(final String queryWithoutClause, int expectedCount) + { + Query query = (Query) em.createQuery(queryWithoutClause, + PersonCassandra.class); + + assertOnFetch(query, 0, expectedCount); + assertOnFetch(query,2,expectedCount); // less records + + assertOnFetch(query,4,expectedCount); // more fetch size than available in db. + assertOnFetch(query,3,expectedCount); // more fetch size than available in db. + + assertOnFetch(query,null,expectedCount); //set to null; + + } + + private void assertOnFetch(Query query, Integer fetchSize, int available) + { + query.setFetchSize(fetchSize); + int counter=0; + Iterator iter = query.iterate(); + + while (iter.hasNext()) + { + Assert.assertNotNull(iter.next()); + counter++; + } + + Assert.assertEquals(counter, fetchSize == null || available < fetchSize?available:fetchSize); + try + { + iter.next(); + Assert.fail(); + } + catch (NoSuchElementException nsex) + { + Assert.assertNotNull(nsex.getMessage()); + } + } + + public void tearDown(final String keyspace) + { + CassandraCli.dropKeySpace(keyspace); + } +} diff --git a/src/kundera-cassandra/src/test/java/org/apache/cassandra/auth/SimpleAuthenticator.java b/src/kundera-cassandra/src/test/java/org/apache/cassandra/auth/SimpleAuthenticator.java new file mode 100644 index 000000000..ed222439b --- /dev/null +++ b/src/kundera-cassandra/src/test/java/org/apache/cassandra/auth/SimpleAuthenticator.java @@ -0,0 +1,275 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package org.apache.cassandra.auth; + +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.cassandra.exceptions.AuthenticationException; +import org.apache.cassandra.exceptions.ConfigurationException; +import org.apache.cassandra.exceptions.InvalidRequestException; +import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.utils.Hex; + +public class SimpleAuthenticator implements IAuthenticator +{ + public final static String PASSWD_FILENAME_PROPERTY = "passwd.properties"; + + public final static String PMODE_PROPERTY = "passwd.mode"; + + public static final String USERNAME_KEY = "username"; + + public static final String PASSWORD_KEY = "password"; + + public enum PasswordMode + { + PLAIN, MD5, + }; + + public AuthenticatedUser defaultUser() + { + // users must log in + return null; + } + + public AuthenticatedUser authenticate(Map credentials) throws AuthenticationException + { + String pmode_plain = System.getProperty(PMODE_PROPERTY); + PasswordMode mode = PasswordMode.PLAIN; + + if (null != pmode_plain) + { + try + { + mode = PasswordMode.valueOf(pmode_plain); + } + catch (Exception e) + { + // this is not worth a StringBuffer + String mode_values = ""; + for (PasswordMode pm : PasswordMode.values()) + mode_values += "'" + pm + "', "; + + mode_values += "or leave it unspecified."; + throw new AuthenticationException("The requested password check mode '" + pmode_plain + + "' is not a valid mode. Possible values are " + mode_values); + } + } + + String pfilename = System.getProperty(PASSWD_FILENAME_PROPERTY); + + String username = null; + CharSequence user = credentials.get(USERNAME_KEY); + if (null == user) + throw new AuthenticationException("Authentication request was missing the required key '" + USERNAME_KEY + + "'"); + else + username = user.toString(); + + String password = null; + CharSequence pass = credentials.get(PASSWORD_KEY); + if (null == pass) + throw new AuthenticationException("Authentication request was missing the required key '" + PASSWORD_KEY + + "'"); + else + password = pass.toString(); + + boolean authenticated = false; + + InputStream in = null; + try + { + in = Thread.currentThread().getContextClassLoader().getResourceAsStream("passwd.properties"); + // in = new BufferedInputStream(new FileInputStream(pfilename)); + Properties props = new Properties(); + props.load(in); + + // note we keep the message here and for the wrong password exactly + // the same to prevent attackers from guessing what users are valid + if (null == props.getProperty(username)) + throw new AuthenticationException(authenticationErrorMessage(mode, username)); + switch (mode) + { + case PLAIN: + authenticated = password.equals(props.getProperty(username)); + break; + case MD5: + authenticated = MessageDigest.isEqual(FBUtilities.threadLocalMD5Digest().digest(password.getBytes()), + Hex.hexToBytes(props.getProperty(username))); + break; + default: + throw new RuntimeException("Unknown PasswordMode " + mode); + } + } + catch (IOException e) + { + throw new RuntimeException("Authentication table file given by property " + PASSWD_FILENAME_PROPERTY + + " could not be opened: " + e.getMessage()); + } + catch (Exception e) + { + throw new RuntimeException("Unexpected authentication problem", e); + } + finally + { + FileUtils.closeQuietly(in); + } + + if (!authenticated) + throw new AuthenticationException(authenticationErrorMessage(mode, username)); + + return new AuthenticatedUser(username); + } + + public void validateConfiguration() throws ConfigurationException + { + String pfilename = System.getProperty(SimpleAuthenticator.PASSWD_FILENAME_PROPERTY); + if (pfilename == null) + { + throw new ConfigurationException("When using " + this.getClass().getCanonicalName() + " " + + SimpleAuthenticator.PASSWD_FILENAME_PROPERTY + " properties must be defined."); + } + } + + static String authenticationErrorMessage(PasswordMode mode, String username) + { + return String.format("Given password in password mode %s could not be validated for user %s", mode, username); + } + + /* + * (non-Javadoc) + * + * @see org.apache.cassandra.auth.IAuthenticator#alter(java.lang.String, + * java.util.Map) + */ + @Override + public void alter(String arg0, Map arg1) throws InvalidRequestException + { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see org.apache.cassandra.auth.IAuthenticator#alterableOptions() + */ + @Override + public Set
tables; + + // private List schemaProperties; + private Properties properties; + + private List dataCenters; + + private String name; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the tables + */ + public List
getTables() + { + return tables; + } + + /** + * @param tables + * the tables to set + */ + public void setTables(List
tables) + { + this.tables = tables; + } + + /** + * @return the schemaProperties + */ + public Properties getSchemaProperties() + { + return properties; + } + + /** + * @param schemaProperties + * the schemaProperties to set + */ + public void setProperties(Properties props) + { + this.properties = props; + } + + /** + * @return the dataCenters + */ + public List getDataCenters() + { + return dataCenters; + } + + /** + * @param dataCenters + * the dataCenters to set + */ + public void setDataCenters(List dataCenters) + { + this.dataCenters = dataCenters; + } + + public static class Table + { + private Properties properties; + + private String name; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the properties + */ + public Properties getProperties() + { + return properties; + } + + /** + * @param properties + * the properties to set + */ + public void setProperties(Properties properties) + { + this.properties = properties; + } + + } + + public static class DataCenter + { + private String name; + + private String value; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the value + */ + public String getValue() + { + return value; + } + + /** + * @param value + * the value to set + */ + public void setValue(String value) + { + this.value = value; + } + } + } + + public static class Connection + { + private Properties properties; + + private List servers; + + /** + * @return the properties + */ + public Properties getProperties() + { + return properties; + } + + /** + * @param properties + * the properties to set + */ + public void setProperties(Properties properties) + { + this.properties = properties; + } + + /** + * @return the servers + */ + public List getServers() + { + return servers; + } + + /** + * @param servers + * the servers to set + */ + public void setServers(List servers) + { + this.servers = servers; + } + + public static class Server + { + private String host; + + private String port; + + private Properties properties; + /** + * @return the host + */ + public String getHost() + { + return host; + } + + /** + * @param host + * the host to set + */ + public void setHost(String host) + { + this.host = host; + } + + /** + * @return the port + */ + public String getPort() + { + return port; + } + + /** + * @param port + * the port to set + */ + public void setPort(String port) + { + this.port = port; + } + + /** + * + * @return + */ + public Properties getProperties() + { + return properties; + } + + /** + * @param properties the properties to set + */ + public void setProperties(Properties properties) + { + this.properties = properties; + } + } + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configuration.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configuration.java new file mode 100644 index 000000000..3587ae8eb --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configuration.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +/** + * Interface to be implemented by different configuration implementations: + * {@link MetamodelConfiguration} + * {@link PersistenceUnitConfiguration} + * {@link SchemaConfiguration} + * {@link ClientFactoryConfiguraton} + * + * @author vivek.mishra + * + */ +interface Configuration +{ + + /** + * Configures and load meta-information for parameterized persistence units. + */ + void configure(); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configurator.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configurator.java new file mode 100644 index 000000000..3f81d0f44 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/Configurator.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Configurator to load and configure different configuration objects. + * + * @author vivek.mishra + * + */ +public final class Configurator +{ + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(Configurator.class); + + /** + * holder for required configuration object. Do we really need to hold these + * as a reference? + */ + private List configurer = new ArrayList(2); + + /** + * Constructor using fields. + * + * @param persistenceUnits + */ + public Configurator(Map properties, String... persistenceUnits) + { + configurer.add(new PersistenceUnitConfiguration(persistenceUnits)); + configurer.add(new MetamodelConfiguration(properties, persistenceUnits)); +// configurer.add(new SchemaConfiguration(properties, persistenceUnits)); +// configurer.add(new ClientFactoryConfiguraton(properties, persistenceUnits)); + } + + /** + * Invokes on each configuration object. + * + */ + public final void configure() + { + for (Configuration conf : configurer) + { + logger.debug("Loading configuration for :" + conf.getClass().getSimpleName()); + conf.configure(); + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/MetamodelConfiguration.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/MetamodelConfiguration.java new file mode 100644 index 000000000..8cfe1b2c1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/MetamodelConfiguration.java @@ -0,0 +1,498 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javassist.bytecode.AnnotationsAttribute; +import javassist.bytecode.ClassFile; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Table; +import javax.persistence.metamodel.Metamodel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.classreading.ClasspathReader; +import com.impetus.kundera.classreading.Reader; +import com.impetus.kundera.classreading.ResourceIterator; +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataBuilder; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.IdDiscriptor; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.GeneratedValueProcessor; +import com.impetus.kundera.metadata.validator.EntityValidator; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.utils.KunderaCoreUtils; + +/** + * The Metamodel configurer: a) Configure application meta data b) loads entity + * metadata and maps metadata. + * + * @author vivek.mishra + */ +public class MetamodelConfiguration extends AbstractSchemaConfiguration implements Configuration +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(MetamodelConfiguration.class); + + /** + * Constructor using persistence units as parameter. + * + * @param persistenceUnits + * persistence units. + */ + public MetamodelConfiguration(Map properties, String... persistenceUnits) + { + super(persistenceUnits, properties); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.configure.Configuration#configure() + */ + @Override + public void configure() + { + log.debug("Loading Entity Metadata..."); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + + for (String persistenceUnit : persistenceUnits) + { + if (appMetadata.getMetamodelMap().get(persistenceUnit.trim()) != null) + { + log.debug("Metadata already exists for the Persistence Unit " + persistenceUnit + ". Nothing to do"); + } + else + { + loadEntityMetadata(persistenceUnit); + } + } + + } + + /** + * Load entity metadata. + * + * @param persistenceUnit + * the persistence unit + */ + private void loadEntityMetadata(String persistenceUnit) + { + if (persistenceUnit == null) + { + throw new IllegalArgumentException( + "Must have a persistenceUnitName in order to load entity metadata, you provided:" + persistenceUnit); + } + + KunderaMetadata kunderaMetadata = KunderaMetadata.INSTANCE; + Map persistentUnitMetadataMap = kunderaMetadata.getApplicationMetadata() + .getPersistenceUnitMetadataMap(); + + /** Classes to scan */ + List classesToScan; + URL[] resources = null; + String client = null; + List managedURLs = null; + if (persistentUnitMetadataMap == null || persistentUnitMetadataMap.isEmpty()) + { + log.error("It is necessary to load Persistence Unit metadata for persistence unit " + persistenceUnit + + " first before loading entity metadata."); + throw new MetamodelLoaderException("load Persistence Unit metadata for persistence unit " + + persistenceUnit + " first before loading entity metadata."); + } + else + { + PersistenceUnitMetadata puMetadata = persistentUnitMetadataMap.get(persistenceUnit); + classesToScan = puMetadata.getManagedClassNames(); + managedURLs = puMetadata.getManagedURLs(); + Map externalProperties = KunderaCoreUtils.getExternalProperties(persistenceUnit, + externalPropertyMap, persistenceUnits); + + client = externalProperties != null ? (String) externalProperties + .get(PersistenceProperties.KUNDERA_CLIENT_FACTORY) : null; + + if (client == null) + { + client = puMetadata.getClient(); + } + } + + /* + * Check whether Classes to scan was provided into persistence.xml If + * yes, load them. Otherwise load them from classpath/ context path + */ + Reader reader; + ApplicationMetadata appMetadata = kunderaMetadata.getApplicationMetadata(); + if (classesToScan == null || classesToScan.isEmpty()) + { + log.info("No class to scan for persistence unit " + persistenceUnit + + ". Entities will be loaded from classpath/ context-path"); + // Entity metadata is not related to any PU, and hence will be + // stored at common place + // persistenceUnit = Constants.COMMON_ENTITY_METADATAS; + + // Check whether all common entity metadata have already been loaded + if (appMetadata.getMetamodelMap().get(persistenceUnit) != null) + { + log.info("All common entitity metadata already loaded, nothing need to be done"); + return; + } + + reader = new ClasspathReader(); + // resources = reader.findResourcesByClasspath(); + } + else + { + reader = new ClasspathReader(classesToScan); + // resources = reader.findResourcesByContextLoader(); + } + + InputStream[] iStreams = null; + if (this.getClass().getClassLoader() instanceof URLClassLoader) + { + URL[] managedClasses = reader.findResources(); + if (managedClasses != null) + { + List managedResources = Arrays.asList(managedClasses); + managedURLs.addAll(managedResources); + } + } + else + { + iStreams = reader.findResourcesAsStream(); + } + + if (managedURLs != null) + { + resources = managedURLs.toArray(new URL[] {}); + } + + // All entities to load should be annotated with @Entity + reader.addValidAnnotations(Entity.class.getName()); + + Metamodel metamodel = appMetadata.getMetamodel(persistenceUnit); + if (metamodel == null) + { + metamodel = new MetamodelImpl(); + } + + Map entityMetadataMap = ((MetamodelImpl) metamodel).getEntityMetadataMap(); + Map> entityNameToClassMap = ((MetamodelImpl) metamodel).getEntityNameToClassMap(); + Map> puToClazzMap = new HashMap>(); + Map entityNameToKeyDiscriptorMap = new HashMap(); + List> classes = new ArrayList>(); + if (resources != null && resources.length > 0) + { + for (URL resource : resources) + { + try + { + ResourceIterator itr = reader.getResourceIterator(resource, reader.getFilter()); + + InputStream is = null; + while ((is = itr.next()) != null) + { + classes.addAll(scanClassAndPutMetadata(is, reader, entityMetadataMap, entityNameToClassMap, + persistenceUnit, client, puToClazzMap, entityNameToKeyDiscriptorMap)); + } + } + catch (IOException e) + { + log.error("Error while retreiving and storing entity metadata. Details:", e); + throw new MetamodelLoaderException("Error while retreiving and storing entity metadata"); + + } + } + } + else if (iStreams != null) + { + try + { + for (InputStream is : iStreams) + { + try + { + classes.addAll(scanClassAndPutMetadata(is, reader, entityMetadataMap, entityNameToClassMap, + persistenceUnit, client, puToClazzMap, entityNameToKeyDiscriptorMap)); + } + finally + { + if (is != null) + { + is.close(); + } + } + } + } + catch (IOException e) + { + log.error("Error while retreiving and storing entity metadata. Details:", e); + throw new MetamodelLoaderException("Error while retreiving and storing entity metadata, Caused by : .", + e); + + } + } + ((MetamodelImpl) metamodel).setEntityMetadataMap(entityMetadataMap); + appMetadata.getMetamodelMap().put(persistenceUnit, metamodel); + appMetadata.setClazzToPuMap(puToClazzMap); + ((MetamodelImpl) metamodel).addKeyValues(entityNameToKeyDiscriptorMap); + // assign JPA metamodel. + ((MetamodelImpl) metamodel).assignEmbeddables(KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetaModelBuilder(persistenceUnit).getEmbeddables()); + ((MetamodelImpl) metamodel).assignManagedTypes(KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetaModelBuilder(persistenceUnit).getManagedTypes()); + ((MetamodelImpl) metamodel).assignMappedSuperClass(KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + + // validateEntityForClientSpecificProperty(classes, persistenceUnit); + + } + + /** + * @param resources + * @param reader + * @throws IOException + * @throws ClassNotFoundException + */ + private void validateEntityForClientSpecificProperty(List> classes, final String persistenceUnit) + { + for (Class clazz : classes) + { + String pu = getPersistenceUnitOfEntity(clazz); + EntityValidator validator = new EntityValidatorImpl(KunderaCoreUtils.getExternalProperties(persistenceUnit, + externalPropertyMap, persistenceUnits)); + if (clazz.isAnnotationPresent(Entity.class) && clazz.isAnnotationPresent(Table.class) + && persistenceUnit.equalsIgnoreCase(pu)) + { + validator.validateEntity(clazz); + } + } + } + + private String getPersistenceUnitOfEntity(Class clazz) + { + String schema = ((Table) clazz.getAnnotation(Table.class)).schema(); + String pu = null; + if (schema != null && schema.indexOf("@") > 0) + { + pu = schema.substring(schema.indexOf("@") + 1, schema.length()); + } + return pu; + } + + /** + * Scan class and put metadata. + * + * @param bits + * the bits + * @param reader + * the reader + * @param entityMetadataMap + * the entity metadata map + * @param entityNameToClassMap + * the entity name to class map + * @param keyDiscriptor + * @param persistence + * unit the persistence unit. + * @throws IOException + * Signals that an I/O exception has occurred. + */ + private List> scanClassAndPutMetadata(InputStream bits, Reader reader, + Map entityMetadataMap, Map> entityNameToClassMap, + String persistenceUnit, String client, Map> clazzToPuMap, + Map entityNameToKeyDiscriptorMap) throws IOException + { + DataInputStream dstream = new DataInputStream(new BufferedInputStream(bits)); + ClassFile cf = null; + String className = null; + List> classes = new ArrayList>(); + + try + { + cf = new ClassFile(dstream); + + className = cf.getName(); + List annotations = new ArrayList(); + + reader.accumulateAnnotations(annotations, + (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.visibleTag)); + reader.accumulateAnnotations(annotations, + (AnnotationsAttribute) cf.getAttribute(AnnotationsAttribute.invisibleTag)); + + // iterate through all valid annotations + for (String validAnn : reader.getValidAnnotations()) + { + // check if the current class has one? + if (annotations.contains(validAnn)) + { + // Class clazz = + // Thread.currentThread().getContextClassLoader().loadClass(className); + + Class clazz = this.getClass().getClassLoader().loadClass(className); + + if (entityNameToClassMap.containsKey(clazz.getSimpleName()) + && !entityNameToClassMap.get(clazz.getSimpleName()).getName().equals(clazz.getName())) + { + throw new MetamodelLoaderException("Name conflict between classes " + + entityNameToClassMap.get(clazz.getSimpleName()).getName() + " and " + clazz.getName() + + ". Make sure no two entity classes with the same name " + + " are specified for persistence unit " + persistenceUnit); + } + + entityNameToClassMap.put(clazz.getSimpleName(), clazz); + + EntityMetadata metadata = entityMetadataMap.get(clazz); + if (null == metadata) + { + log.debug("Metadata not found in cache for " + clazz.getName()); + // double check locking. + synchronized (clazz) + { + if (null == metadata) + { + MetadataBuilder metadataBuilder = new MetadataBuilder(persistenceUnit, client, + KunderaCoreUtils.getExternalProperties(persistenceUnit, externalPropertyMap, + persistenceUnits)); + metadata = metadataBuilder.buildEntityMetadata(clazz); + + // in case entity's pu does not belong to parse + // persistence unit, it will be null. + if (metadata != null) + { + entityMetadataMap.put(clazz.getName(), metadata); + mapClazztoPu(clazz, persistenceUnit, clazzToPuMap); + processGeneratedValueAnnotation(clazz, persistenceUnit, metadata, + entityNameToKeyDiscriptorMap); + } + } + } + } + + // TODO : + onValidateClientProperties(classes, clazz, persistenceUnit); + } + } + } + catch (ClassNotFoundException e) + { + log.error("Class " + className + " not found, it won't be loaded as entity"); + } + finally + { + if (dstream != null) + { + dstream.close(); + } + if (bits != null) + { + bits.close(); + } + } + + return classes; + } + + /** + * @param clazz + */ + private List> onValidateClientProperties(List> classes, Class clazz, + final String persistenceUnit) + { + if (clazz.isAnnotationPresent(Entity.class) && clazz.isAnnotationPresent(Table.class)) + { + classes.add(clazz); + } + return classes; + } + + /** + * Method to prepare class simple name to list of pu's mapping. 1 class can + * be mapped to multiple persistence units, in case of RDBMS, in other cases + * it will only be 1! + * + * @param clazz + * entity class to be mapped. + * @param pu + * current persistence unit name + * @param clazzToPuMap + * collection holding mapping. + * @return map holding mapping. + */ + private Map> mapClazztoPu(Class clazz, String pu, Map> clazzToPuMap) + { + List puCol = new ArrayList(1); + if (clazzToPuMap == null) + { + clazzToPuMap = new HashMap>(); + } + else + { + if (clazzToPuMap.containsKey(clazz.getName())) + { + puCol = clazzToPuMap.get(clazz.getName()); + } + } + + if (!puCol.contains(pu)) + { + puCol.add(pu); + clazzToPuMap.put(clazz.getName(), puCol); + } + + return clazzToPuMap; + } + + private void processGeneratedValueAnnotation(Class clazz, String persistenceUnit, EntityMetadata m, + Map entityNameToKeyDiscriptorMap) + { + GeneratedValueProcessor processer = new GeneratedValueProcessor(); + String pu = getPersistenceUnitOfEntity(clazz); + String clientFactoryName = KunderaMetadataManager.getPersistenceUnitMetadata(m.getPersistenceUnit()) + .getClient(); + if (pu != null && pu.equals(persistenceUnit) + || clientFactoryName.equalsIgnoreCase("com.impetus.client.rdbms.RDBMSClientFactory")) + { + Field f = (Field) m.getIdAttribute().getJavaMember(); + + if (f.isAnnotationPresent(GeneratedValue.class)) + { + processer.process(clazz, f, m, entityNameToKeyDiscriptorMap); + } + } + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfiguration.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfiguration.java new file mode 100644 index 000000000..c7c963d41 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfiguration.java @@ -0,0 +1,171 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.spi.PersistenceUnitTransactionType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaPersistence; +import com.impetus.kundera.loader.PersistenceLoaderException; +import com.impetus.kundera.loader.PersistenceXMLLoader; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.utils.InvalidConfigurationException; + +/** + * The Class PersistenceUnitConfiguration: 1) Find and load/configure + * persistence unit meta data. Earlier it was PersistenceUnitLoader. + * + * @author vivek.mishra + */ + +public class PersistenceUnitConfiguration extends AbstractSchemaConfiguration implements Configuration +{ + + /** The log instance. */ + private static Logger log = LoggerFactory.getLogger(PersistenceUnitConfiguration.class); + + /** The Constant PROVIDER_IMPLEMENTATION_NAME. */ + private static final String PROVIDER_IMPLEMENTATION_NAME = KunderaPersistence.class.getName(); + + /** + * Constructor parameterised with persistence units. + * + * @param persistenceUnits + * persistence units. + */ + public PersistenceUnitConfiguration(String... persistenceUnits) + { + super(persistenceUnits, null); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.configure.Configuration#configure() + */ + @Override + public void configure() + { + log.info("Loading Metadata from persistence.xml ..."); + KunderaMetadata kunderaMetadata = KunderaMetadata.INSTANCE; + + ApplicationMetadata appMetadata = kunderaMetadata.getApplicationMetadata(); + + Map metadatas; + try + { + metadatas = findPersistenceMetadatas(); + for (String persistenceUnit : persistenceUnits) + { + if (!metadatas.containsKey(persistenceUnit)) + { + log.error("Unconfigured persistence unit: " + persistenceUnit + + " please validate with persistence.xml"); + throw new PersistenceUnitConfigurationException("Invalid persistence unit: " + persistenceUnit + + " provided"); + } + } + log.info("Finishing persistence unit metadata configuration ..."); + appMetadata.addPersistenceUnitMetadata(metadatas); + } + catch (InvalidConfigurationException icex) + { + log.error("Error occurred during persistence unit configuration, Caused by: .", icex); + throw new PersistenceLoaderException(icex); + } + } + + /** + * Find persistence meta data. Loads configured persistence.xml and load all + * provided configurations within persistence meta data as per @see JPA 2.0 + * specifications. + * + * @return the list configure persistence unit meta data. + */ + private Map findPersistenceMetadatas() throws InvalidConfigurationException + { + + Enumeration xmls = null; + try + { + xmls = this.getClass().getClassLoader().getResources("META-INF/persistence.xml"); + +// if (xmls == null || !xmls.hasMoreElements()) +// { +// xmls = Thread.currentThread().getClass().getClassLoader().getResources("META-INF/persistence.xml"); +// } + } + catch (IOException ioex) + { + log.warn("Error while loading persistence.xml Caused by:" + ioex.getMessage()); + } + + if (xmls == null || !xmls.hasMoreElements()) + { + log.error("Could not find any META-INF/persistence.xml file in the classpath"); + throw new InvalidConfigurationException("Could not find any META-INF/persistence.xml file in the classpath"); + } + + Set persistenceUnitNames = new HashSet(); + Map persistenceUnitMap = new HashMap(); + while (xmls.hasMoreElements()) + { + URL url = xmls.nextElement(); + + log.trace("Analysing persistence.xml: " + url); + List metadataFiles = PersistenceXMLLoader.findPersistenceUnits(url, + PersistenceUnitTransactionType.RESOURCE_LOCAL); + + // Pick only those that have Kundera Provider + for (PersistenceUnitMetadata metadata : metadataFiles) + { + // check for unique names + if (persistenceUnitNames.contains(metadata.getPersistenceUnitName())) + { + if (log.isWarnEnabled()) + { + log.warn("Duplicate persistence-units for name: " + metadata.getPersistenceUnitName() + + ". verify your persistence.xml file"); + } + } + + // check for provider + if (metadata.getPersistenceProviderClassName() == null + || PROVIDER_IMPLEMENTATION_NAME.equalsIgnoreCase(metadata.getPersistenceProviderClassName())) + { + persistenceUnitMap.put(metadata.getPersistenceUnitName(), metadata); + } + + // add to check for duplicate persistence unit. + persistenceUnitNames.add(metadata.getPersistenceUnitName()); + } + } + return persistenceUnitMap; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfigurationException.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfigurationException.java new file mode 100644 index 000000000..a7912eebb --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PersistenceUnitConfigurationException.java @@ -0,0 +1,54 @@ +/** + * + */ +package com.impetus.kundera.configure; + +import com.impetus.kundera.KunderaException; + +/** + * @author Kuldeep Mishra + * + */ +public class PersistenceUnitConfigurationException extends KunderaException +{ + + /** Default Serial Version UID. */ + private static final long serialVersionUID = 1L; + + /** + * + */ + public PersistenceUnitConfigurationException() + { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param paramString + * @param paramThrowable + */ + public PersistenceUnitConfigurationException(String paramString, Throwable paramThrowable) + { + super(paramString, paramThrowable); + // TODO Auto-generated constructor stub + } + + /** + * @param paramString + */ + public PersistenceUnitConfigurationException(String paramString) + { + super(paramString); + // TODO Auto-generated constructor stub + } + + /** + * @param paramThrowable + */ + public PersistenceUnitConfigurationException(Throwable paramThrowable) + { + super(paramThrowable); + // TODO Auto-generated constructor stub + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/PropertyReader.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PropertyReader.java new file mode 100644 index 000000000..fcf6435a9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/PropertyReader.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +/** + * Property reader to read client specific property. + * + * @author kuldeep.mishra + * + */ +public interface PropertyReader +{ + /** + * reads all properties from property. + * + * @param string + */ + void read(String string); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/SchemaConfiguration.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/SchemaConfiguration.java new file mode 100644 index 000000000..e55e310cb --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/SchemaConfiguration.java @@ -0,0 +1,560 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Embeddable; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.metamodel.SingularAttribute; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.configure.schema.CollectionColumnInfo; +import com.impetus.kundera.configure.schema.ColumnInfo; +import com.impetus.kundera.configure.schema.EmbeddedColumnInfo; +import com.impetus.kundera.configure.schema.IndexInfo; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.TableInfo; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.ClientFactory; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.metadata.model.IdDiscriptor; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.PropertyIndex; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.processor.IndexProcessor; +import com.impetus.kundera.metadata.validator.EntityValidator; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.KunderaCoreUtils; + +/** + * Schema configuration implementation to support ddl_schema_creation + * functionality. e.g. kundera_ddl_auto_prepare + * (create,create-drop,validate,update) + * + * @author Kuldeep.Kumar + * + */ +public class SchemaConfiguration extends AbstractSchemaConfiguration implements Configuration +{ + /** The log. */ + private static Logger log = LoggerFactory.getLogger(SchemaConfiguration.class); + + /** + * pu to schema metadata map . + */ + private Map> puToSchemaMetadata = new HashMap>(); + + /** + * Constructor using persistence units as parameter. + * + * @param persistenceUnits + * persistence units. + */ + public SchemaConfiguration(Map externalProperties, String... persistenceUnits) + { + super(persistenceUnits, externalProperties); + } + + @Override + /** + * configure method responsible for creating pu to schema metadata map for each entity in class path. + * + */ + public void configure() + { + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + + EntityValidator validator = new EntityValidatorImpl(externalPropertyMap); + + // TODO, FIXME: Refactoring is required. + for (String persistenceUnit : persistenceUnits) + { + log.info("Configuring schema export for : " + persistenceUnit); + List tableInfos = getSchemaInfo(persistenceUnit); + + Map entityMetadataMap = getEntityMetadataCol(appMetadata, persistenceUnit); + + PersistenceUnitMetadata puMetadata = appMetadata.getPersistenceUnitMetadata(persistenceUnit); + + // Iterate each entity metadata. + for (EntityMetadata entityMetadata : entityMetadataMap.values()) + { + // get entity metadata(table info as well as columns) + // if table info exists, get it from map. + boolean found = false; + Type type = entityMetadata.getType(); + Class idClassName = entityMetadata.getIdAttribute() != null ? entityMetadata.getIdAttribute() + .getJavaType() : null; + + String idName = entityMetadata.getIdAttribute() != null ? ((AbstractAttribute) entityMetadata + .getIdAttribute()).getJPAColumnName() : null; + + TableInfo tableInfo = new TableInfo(entityMetadata.getTableName(), type.name(), idClassName, idName); + + // check for tableInfos not empty and contains the present + // tableInfo. + if (!tableInfos.isEmpty() && tableInfos.contains(tableInfo)) + { + found = true; + int idx = tableInfos.indexOf(tableInfo); + tableInfo = tableInfos.get(idx); + addColumnToTableInfo(entityMetadata, type, tableInfo); + } + else + { + addColumnToTableInfo(entityMetadata, type, tableInfo); + } + + List relations = entityMetadata.getRelations(); + + parseRelations(persistenceUnit, tableInfos, entityMetadata, tableInfo, relations); + + if (!found) + { + tableInfos.add(tableInfo); + } + // Add table for GeneratedValue if opted TableStrategy + addTableGenerator(appMetadata, persistenceUnit, tableInfos, entityMetadata, idClassName, idName); + + // Validating entity against counter column family. + validator.validateEntity(entityMetadata.getEntityClazz()); + } + + puToSchemaMetadata.put(persistenceUnit, tableInfos); + + } + + // Need to iterate, as in case of non unary relations + for (String persistenceUnit : persistenceUnits) + { + PersistenceUnitMetadata puMetadata = appMetadata.getPersistenceUnitMetadata(persistenceUnit); + + if (externalPropertyMap != null + && externalPropertyMap.get(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) != null + || puMetadata.getProperty(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) != null) + { + SchemaManager schemaManager = getSchemaManagerForPu(persistenceUnit); + + if (schemaManager != null) + { + schemaManager.exportSchema(persistenceUnit, puToSchemaMetadata.get(persistenceUnit)); + } + } + } + } + + /** + * Return schema manager for pu. + * + * @param persistenceUnit + * @return + */ + private SchemaManager getSchemaManagerForPu(final String persistenceUnit) + { + SchemaManager schemaManager = null; + Map externalProperties = KunderaCoreUtils.getExternalProperties(persistenceUnit, + externalPropertyMap, persistenceUnits); + if (getSchemaProperty(persistenceUnit, externalProperties) != null + && !getSchemaProperty(persistenceUnit, externalProperties).isEmpty()) + { + ClientFactory clientFactory = ClientResolver.getClientFactory(persistenceUnit); + schemaManager = clientFactory != null ? clientFactory.getSchemaManager(externalProperties) : null; + } + return schemaManager; + } + + /** + * Add tableGenerator to table info. + * + * @param appMetadata + * @param persistenceUnit + * @param tableInfos + * @param entityMetadata + * @param idClassName + * @param idName + * @param isCompositeId + */ + private void addTableGenerator(ApplicationMetadata appMetadata, String persistenceUnit, List tableInfos, + EntityMetadata entityMetadata, Class idClassName, String idName) + { + Metamodel metamodel = appMetadata.getMetamodel(persistenceUnit); + IdDiscriptor keyValue = ((MetamodelImpl) metamodel).getKeyValue(entityMetadata.getEntityClazz().getName()); + if (keyValue != null && keyValue.getTableDiscriptor() != null) + { + TableInfo tableGeneratorDiscriptor = new TableInfo(keyValue.getTableDiscriptor().getTable(), + "CounterColumnType", String.class, idName); + if (!tableInfos.contains(tableGeneratorDiscriptor)) + { + tableGeneratorDiscriptor.addColumnInfo(getJoinColumn(tableGeneratorDiscriptor, keyValue + .getTableDiscriptor().getValueColumnName(), Long.class)); + tableInfos.add(tableGeneratorDiscriptor); + } + } + } + + /** + * parse the relations of entites . + * + * @param persistenceUnit + * @param tableInfos + * @param entityMetadata + * @param tableInfo + * @param relations + */ + private void parseRelations(String persistenceUnit, List tableInfos, EntityMetadata entityMetadata, + TableInfo tableInfo, List relations) + { + for (Relation relation : relations) + { + Class entityClass = relation.getTargetEntity(); + EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + if (targetEntityMetadata == null) + { + log.error("Persistence unit for class : " + entityClass + " is not loaded"); + throw new SchemaGenerationException("Persistence unit for class : " + entityClass + " is not loaded"); + } + ForeignKey relationType = relation.getType(); + + // if relation type is one to many or join by primary key + if (targetEntityMetadata != null && relationType.equals(ForeignKey.ONE_TO_MANY) + && relation.getJoinColumnName() != null) + { + // if self association + if (targetEntityMetadata.equals(entityMetadata)) + { + tableInfo.addColumnInfo(getJoinColumn(tableInfo, relation.getJoinColumnName(), entityMetadata + .getIdAttribute().getJavaType())); + } + else + { + String pu = targetEntityMetadata.getPersistenceUnit(); + Type targetEntityType = targetEntityMetadata.getType(); + Class idClass = targetEntityMetadata.getIdAttribute().getJavaType(); + String idName = ((AbstractAttribute) targetEntityMetadata.getIdAttribute()).getJPAColumnName(); + TableInfo targetTableInfo = new TableInfo(targetEntityMetadata.getTableName(), + targetEntityType.name(), idClass, idName); + + // In case of different persistence unit. case for poly glot + // persistence. + if (!pu.equals(persistenceUnit)) + { + List targetTableInfos = getSchemaInfo(pu); + + addJoinColumnToInfo(relation.getJoinColumnName(), targetTableInfo, targetTableInfos, + entityMetadata); + + // add for newly discovered persistence unit. + puToSchemaMetadata.put(pu, targetTableInfos); + } + else + { + addJoinColumnToInfo(relation.getJoinColumnName(), targetTableInfo, tableInfos, entityMetadata); + } + } + } + // if relation type is one to one or many to one. + else if (relation.isUnary() && relation.getJoinColumnName() != null) + { + tableInfo.addColumnInfo(getJoinColumn(tableInfo, relation.getJoinColumnName(), targetEntityMetadata + .getIdAttribute().getJavaType())); + } + // if relation type is many to many and relation via join table. + else if ((relationType.equals(ForeignKey.MANY_TO_MANY)) && (entityMetadata.isRelationViaJoinTable())) + { + JoinTableMetadata joinTableMetadata = relation.getJoinTableMetadata(); + String joinTableName = joinTableMetadata != null ? joinTableMetadata.getJoinTableName() : null; + String joinColumnName = joinTableMetadata != null ? (String) joinTableMetadata.getJoinColumns() + .toArray()[0] : null; + String inverseJoinColumnName = joinTableMetadata != null ? (String) joinTableMetadata + .getInverseJoinColumns().toArray()[0] : null; + if (joinTableName != null) + { + TableInfo joinTableInfo = new TableInfo(joinTableName, Type.COLUMN_FAMILY.name(), String.class, + joinColumnName.concat(inverseJoinColumnName)); + if (!tableInfos.isEmpty() && !tableInfos.contains(joinTableInfo) || tableInfos.isEmpty()) + { + joinTableInfo.addColumnInfo(getJoinColumn(joinTableInfo, joinColumnName, entityMetadata + .getIdAttribute().getJavaType())); + joinTableInfo.addColumnInfo(getJoinColumn(joinTableInfo, inverseJoinColumnName, entityMetadata + .getIdAttribute().getJavaType())); + + // // Do not delete above lines. Currently join table + // columns are of type string only. + // // It needs to be fixed later. + // joinTableInfo.addColumnInfo(getJoinColumn(joinTableInfo, + // joinColumnName, String.class)); + // joinTableInfo.addColumnInfo(getJoinColumn(joinTableInfo, + // inverseJoinColumnName, String.class)); + + tableInfos.add(joinTableInfo); + } + } + } + } + } + + /** + * adds join column name to the table Info of entity. + * + * @param joinColumn + * @param targetTableInfo + * @param targetTableInfos + */ + private void addJoinColumnToInfo(String joinColumn, TableInfo targetTableInfo, List targetTableInfos, + EntityMetadata m) + { + ColumnInfo columnInfoOfJoinColumn = getJoinColumn(targetTableInfo, joinColumn, m.getIdAttribute() + .getBindableJavaType()); + if (!targetTableInfos.isEmpty() && targetTableInfos.contains(targetTableInfo)) + { + int idx = targetTableInfos.indexOf(targetTableInfo); + targetTableInfo = targetTableInfos.get(idx); + if (!targetTableInfo.getColumnMetadatas().contains(columnInfoOfJoinColumn)) + { + targetTableInfo.addColumnInfo(columnInfoOfJoinColumn); + } + } + else + { + if (!targetTableInfo.getColumnMetadatas().contains(columnInfoOfJoinColumn)) + { + targetTableInfo.addColumnInfo(columnInfoOfJoinColumn); + } + targetTableInfos.add(targetTableInfo); + } + } + + /** + * Adds column to table info of entity. + * + * @param entityMetadata + * @param type + * @param tableInfo + */ + private void addColumnToTableInfo(EntityMetadata entityMetadata, Type type, TableInfo tableInfo) + { + // Add columns to table info. + Metamodel metaModel = KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + EntityType entityType = metaModel.entity(entityMetadata.getEntityClazz()); + Map columns = entityMetadata.getIndexProperties(); + + Set attributes = entityType.getAttributes(); + + Iterator iter = attributes.iterator(); + while (iter.hasNext()) + { + Attribute attr = iter.next(); + if (!attr.isAssociation()) + { + if (((MetamodelImpl) metaModel).isEmbeddable(attr.getJavaType())) + { + EmbeddableType embeddable = metaModel.embeddable(attr.getJavaType()); + + EmbeddedColumnInfo embeddedColumnInfo = getEmbeddedColumn(tableInfo, embeddable, attr.getName(), + attr.getJavaType()); + + if (!tableInfo.getEmbeddedColumnMetadatas().contains(embeddedColumnInfo)) + { + tableInfo.addEmbeddedColumnInfo(embeddedColumnInfo); + } + } + else if (!attr.isCollection() && !((SingularAttribute) attr).isId()) + { + ColumnInfo columnInfo = getColumn(tableInfo, attr, + columns != null ? columns.get(((AbstractAttribute) attr).getJPAColumnName()) : null); + if (!tableInfo.getColumnMetadatas().contains(columnInfo)) + { + tableInfo.addColumnInfo(columnInfo); + } + } + else if(attr.isCollection() && MetadataUtils.isBasicElementCollectionField((Field)attr.getJavaMember())) + { + CollectionColumnInfo cci = new CollectionColumnInfo(); + cci.setCollectionColumnName(((AbstractAttribute) attr).getJPAColumnName()); + cci.setType(attr.getJavaType()); + cci.setGenericClasses(PropertyAccessorHelper.getGenericClasses((Field)attr.getJavaMember())); + + tableInfo.addCollectionColumnMetadata(cci); + } + } + } + } + + /** + * Returns list of configured table/column families. + * + * @param persistenceUnit + * persistence unit, for which schema needs to be fetched. + * + * @return list of {@link TableInfo} + */ + private List getSchemaInfo(String persistenceUnit) + { + List tableInfos = puToSchemaMetadata.get(persistenceUnit); + // if no TableInfos for given persistence unit. + if (tableInfos == null) + { + tableInfos = new ArrayList(); + } + return tableInfos; + } + + /** + * Returns map of entity metdata {@link EntityMetadata}. + * + * @param appMetadata + * application metadata + * @param persistenceUnit + * persistence unit + * @return map of entity metadata. + */ + private Map getEntityMetadataCol(ApplicationMetadata appMetadata, String persistenceUnit) + { + Metamodel metaModel = appMetadata.getMetamodel(persistenceUnit); + Map entityMetadataMap = ((MetamodelImpl) metaModel).getEntityMetadataMap(); + return entityMetadataMap; + } + + /** + * Get Embedded column info. + * + * @param embeddableType + * @param embeddableColName + * @param embeddedEntityClass + * @return + */ + private EmbeddedColumnInfo getEmbeddedColumn(TableInfo tableInfo, EmbeddableType embeddableType, + String embeddableColName, Class embeddedEntityClass) + { + EmbeddedColumnInfo embeddedColumnInfo = new EmbeddedColumnInfo(embeddableType); + embeddedColumnInfo.setEmbeddedColumnName(embeddableColName); + Map indexedColumns = IndexProcessor.getIndexesOnEmbeddable(embeddedEntityClass); + List columns = new ArrayList(); + + Set attributes = embeddableType.getAttributes(); + Iterator iter = attributes.iterator(); + + while (iter.hasNext()) + { + Attribute attr = iter.next(); + columns.add(getColumn(tableInfo, attr, indexedColumns.get(attr.getName()))); + } + embeddedColumnInfo.setColumns(columns); + return embeddedColumnInfo; + } + + /** + * getColumn method return ColumnInfo for the given column + * + * @param Object + * of Column. + * @return Object of ColumnInfo. + */ + private ColumnInfo getColumn(TableInfo tableInfo, Attribute column, PropertyIndex indexedColumn) + { + ColumnInfo columnInfo = new ColumnInfo(); + + if (column.getJavaType().isEnum()) + { + columnInfo.setType(String.class); + } + else + { + columnInfo.setType(column.getJavaType()); + } + columnInfo.setColumnName(((AbstractAttribute) column).getJPAColumnName()); + if (indexedColumn != null && indexedColumn.getName() != null) + { + columnInfo.setIndexable(true); + IndexInfo indexInfo = new IndexInfo(((AbstractAttribute) column).getJPAColumnName(), + indexedColumn.getMax(), indexedColumn.getMin(), indexedColumn.getIndexType()); + tableInfo.addToIndexedColumnList(indexInfo); + // Add more if required + } + return columnInfo; + } + + /** + * getJoinColumn method return ColumnInfo for the join column + * + * @param columnType + * + * @param String + * joinColumnName. + * @return ColumnInfo object columnInfo. + */ + private ColumnInfo getJoinColumn(TableInfo tableInfo, String joinColumnName, Class columnType) + { + ColumnInfo columnInfo = new ColumnInfo(); + columnInfo.setColumnName(joinColumnName); + columnInfo.setIndexable(true); + + IndexInfo indexInfo = new IndexInfo(joinColumnName); + tableInfo.addToIndexedColumnList(indexInfo); + + columnInfo.setType(columnType); + return columnInfo; + } + + /** + * getKunderaProperty method return auto schema generation property for give + * persistence unit. + * + * @param externalProperties + * + * @param String + * persistenceUnit. + * @return value of kundera auto ddl in form of String. + */ + private String getSchemaProperty(String persistenceUnit, Map externalProperties) + { + PersistenceUnitMetadata persistenceUnitMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit); + String autoDdlOption = externalProperties != null ? (String) externalProperties + .get(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) : null; + if (autoDdlOption == null) + { + autoDdlOption = persistenceUnitMetadata != null ? persistenceUnitMetadata + .getProperty(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE) : null; + } + return autoDdlOption; + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/CollectionColumnInfo.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/CollectionColumnInfo.java new file mode 100644 index 000000000..f7ec2df21 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/CollectionColumnInfo.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure.schema; + +import java.util.List; + + +/** + * @author amresh.singh + * + */ +public class CollectionColumnInfo +{ + /** The collection column name variable .*/ + private String collectionColumnName; + + /** + * Type of collection column among: + * 1. java.util.List + * 2. java.util.Set + * 3. java.util.Map + */ + private Class type; + + /** + * Generic classes of data held in collection + * would old one element for Set and List, two for Map + */ + private List> genericClasses; + + /** + * @return the collectionColumnName + */ + public String getCollectionColumnName() + { + return collectionColumnName; + } + + /** + * @param collectionColumnName the collectionColumnName to set + */ + public void setCollectionColumnName(String collectionColumnName) + { + this.collectionColumnName = collectionColumnName; + } + + /** + * @return the type + */ + public Class getType() + { + return type; + } + + /** + * @param type the type to set + */ + public void setType(Class type) + { + this.type = type; + } + + /** + * @return the genericClasses + */ + public List> getGenericClasses() + { + return genericClasses; + } + + /** + * @param genericClasses the genericClasses to set + */ + public void setGenericClasses(List> genericClasses) + { + this.genericClasses = genericClasses; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/ColumnInfo.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/ColumnInfo.java new file mode 100644 index 000000000..164660a18 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/ColumnInfo.java @@ -0,0 +1,151 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.configure.schema; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * The Class ColumnInfo holds column related information. + * + * @author Kuldeep.Kumar + */ +public class ColumnInfo +{ + + /** The is indexable variable for indexing the column. */ + private boolean isIndexable = false; + + /** The column name variable . */ + private String columnName; + + /** The type variable. */ + private Class type; + + /** + * Instantiates a new column info. + */ + public ColumnInfo() + { + + } + + /** + * Equals method compare two object of columnInfo on the basis of their + * name. + * + * @param Object + * instance. + * + * @return boolean value. + */ + @Override + public boolean equals(Object obj) + { + + // / if object's class and column name matches then return true; + + return obj != null && obj instanceof ColumnInfo && ((ColumnInfo) obj).columnName != null ? this.columnName != null + && this.columnName.equals(((ColumnInfo) obj).columnName) + : false; + + } + + @Override + /** + * returns the hash code for object. + * + */ + public int hashCode() + { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + /** + * returns the string representation of object . + * + */ + public String toString() + { + StringBuilder strBuilder = new StringBuilder("type:==> "); + strBuilder.append(type); + strBuilder.append(" | columnName: ==>"); + strBuilder.append(columnName); + strBuilder.append(" | isIndexable: ==>"); + strBuilder.append(isIndexable); + return strBuilder.toString(); + } + + /** + * Gets the column name. + * + * @return the columnName + */ + public String getColumnName() + { + return columnName; + } + + /** + * Sets the column name. + * + * @param columnName + * the columnName to set + */ + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + /** + * Checks if is indexable. + * + * @return the isIndexable + */ + public boolean isIndexable() + { + return isIndexable; + } + + /** + * Sets the indexable. + * + * @param isIndexable + * the isIndexable to set + */ + public void setIndexable(boolean isIndexable) + { + this.isIndexable = isIndexable; + } + + /** + * @return the type + */ + public Class getType() + { + return type; + } + + /** + * @param type + * the type to set + */ + public void setType(Class type) + { + this.type = type; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/EmbeddedColumnInfo.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/EmbeddedColumnInfo.java new file mode 100644 index 000000000..70715034e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/EmbeddedColumnInfo.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.configure.schema; + +import java.util.List; + +import javax.persistence.metamodel.EmbeddableType; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * The Class ColumnInfo holds the information of Embedded Columns. + * + * @author Kuldeep.Kumar + * + */ +public class EmbeddedColumnInfo +{ + /** The embedded column name variable . */ + private String embeddedColumnName; + + /** The list of columns variable is columns . */ + private List columns; + + private EmbeddableType embeddable; + + /** + * @param metaModel + */ + public EmbeddedColumnInfo(EmbeddableType metaModel) + { + this.embeddable = metaModel; + } + + /** + * @return the embeddable + */ + public EmbeddableType getEmbeddable() + { + return embeddable; + } + + /** + * @return the embeddedColumnName + */ + public String getEmbeddedColumnName() + { + return embeddedColumnName; + } + + /** + * @param embeddedColumnName + * the embeddedColumnName to set + */ + public void setEmbeddedColumnName(String embeddedColumnName) + { + this.embeddedColumnName = embeddedColumnName; + } + + /** + * @return the columns + */ + public List getColumns() + { + return columns; + } + + /** + * @param columns + * the columns to set + */ + public void setColumns(List columns) + { + this.columns = columns; + } + + /** + * Equals method compare two object of EmbeddedColumnInfo on the basis of + * their name. + * + * @param Object + * instance. + * + * @return boolean value. + */ + @Override + public boolean equals(Object obj) + { + return obj != null && obj instanceof EmbeddedColumnInfo + && ((EmbeddedColumnInfo) obj).embeddedColumnName != null ? this.embeddedColumnName != null + && this.embeddedColumnName.equals(((EmbeddedColumnInfo) obj).embeddedColumnName) : false; + } + + @Override + /** + * returns the hash code for object. + * + */ + public int hashCode() + { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + /** + * returns the string representation of object . + * + */ + public String toString() + { + StringBuilder strBuilder = new StringBuilder("embeddedColumnName:==> "); + strBuilder.append(embeddedColumnName); + return strBuilder.toString(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/IndexInfo.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/IndexInfo.java new file mode 100644 index 000000000..ec723c409 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/IndexInfo.java @@ -0,0 +1,102 @@ +package com.impetus.kundera.configure.schema; + +/** + * Class IndexInfo holds the information about index for a column. + * + * @author Kuldeep.Mishra + * + */ +public class IndexInfo +{ + /** The column name variable . */ + private String columnName; + + /** Maximum allowed value for this column */ + private Integer maxValue; + + /** Minimum allowed value for this column */ + private Integer minValue; + + /** The index type. */ + private String indexType; + + public IndexInfo(String columnName, Integer maxValue, Integer minValue, String indexType) + { + this.columnName = columnName; + this.maxValue = maxValue; + this.minValue = minValue; + this.indexType = indexType; + } + + public IndexInfo(String columnName) + { + this(columnName, null, null, null); + } + + public String getColumnName() + { + return columnName; + } + + public void setColumnName(String columnName) + { + this.columnName = columnName; + } + + public Integer getMaxValue() + { + return maxValue; + } + + public void setMaxValue(Integer maxValue) + { + this.maxValue = maxValue; + } + + public Integer getMinValue() + { + return minValue; + } + + public void setMinValue(Integer minValue) + { + this.minValue = minValue; + } + + public String getIndexType() + { + return indexType; + } + + public void setIndexType(String indexType) + { + this.indexType = indexType; + } + + /** + * Equals method compare two object of columnInfo on the basis of their + * name. + * + * @param Object + * instance. + * + * @return boolean value. + */ + @Override + public boolean equals(Object columnName) + { + // / if column name matches then return true; + + return columnName != null ? this.columnName.equals(columnName.toString()) : false; + } + + @Override + /** + * returns the string representation of object . + * + */ + public String toString() + { + return columnName; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/SchemaGenerationException.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/SchemaGenerationException.java new file mode 100644 index 000000000..51b8f6abc --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/SchemaGenerationException.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.configure.schema; + +import com.impetus.kundera.KunderaException; + +/** + * Exception class for all type of exceptions thrown by SchemaManager during + * generating schema. + * + * @author Kuldeep.Kumar + */ +public class SchemaGenerationException extends KunderaException +{ + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 3855497974944993364L; + + /** The data store name. */ + private String dataStoreName; + + /** The schema name. */ + private String schemaName; + + /** The table name. */ + private String tableName; + + /** + * Instantiates a new schemaGeneration exception. + * + * @param dataStore + * the data store + * @param schema + * the schema + */ + public SchemaGenerationException(String arg0, String dataStore, String schema) + { + super(arg0); + this.dataStoreName = dataStore; + this.schemaName = schema; + } + + /** + * Instantiates a new schemaGeneration exception. + * + * @param arg0 + * the arg0 + * @param dataStore + * the data store + * @param schema + * the schema + * @param table + * the table + */ + public SchemaGenerationException(String arg0, String dataStore, String schema, String table) + { + super(arg0); + this.dataStoreName = dataStore; + this.schemaName = schema; + this.tableName = table; + } + + /** + * Instantiates a new schemaGeneration exception. + * + * @param arg0 + * the arg0 + */ + public SchemaGenerationException(Throwable arg0) + { + super(arg0); + } + + /** + * Instantiates a new schemaGeneration exception. + * + * @param arg0 + * the arg0 + * @param dataStore + * the data store + */ + public SchemaGenerationException(Throwable arg0, String dataStore) + { + super(arg0); + this.dataStoreName = dataStore; + } + + /** + * Instantiates a new schemaGeneration exception. + * + * @param arg0 + * the arg0 + * @param dataStore + * the data store + * @param schema + * the schema + */ + public SchemaGenerationException(Throwable arg0, String dataStore, String schema) + { + super(arg0); + this.dataStoreName = dataStore; + this.schemaName = schema; + } + + /** + * Instantiates a new schemaGeneration exception. + * + * @param arg0 + * the arg0 + * @param arg1 + * the arg1 + * @param dataStore + * the data store + */ + public SchemaGenerationException(String arg0, Throwable arg1, String dataStore) + { + super(arg0, arg1); + this.dataStoreName = dataStore; + } + + public SchemaGenerationException(String arg0, Throwable arg1, String dataStoreName, String databaseName) + { + super(arg0, arg1); + this.dataStoreName = dataStoreName; + this.schemaName = databaseName; + } + + public SchemaGenerationException(String arg0) + { + super(arg0); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/TableInfo.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/TableInfo.java new file mode 100644 index 000000000..d90dee354 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/TableInfo.java @@ -0,0 +1,310 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure.schema; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * TableInfo class holds table creation related information. + * + * @author Kuldeep.Kumar + * + */ +public class TableInfo +{ + /** The table name. */ + private String tableName; + + /** The column metadatas. */ + private List columnMetadatas; + + /** The table id class. */ + private Class idClazz; + + /** The table id name. */ + private String idColumnName; + + /** The type. */ + private String type; + + /** The embedded column metadatas. */ + private List embeddedColumnMetadatas; + + /** The collection column metadatas. */ + private List collectionColumnMetadatas; + + /** + * + */ + private List columnToBeIndexed = new ArrayList(); + + /** + * Instantiates a new table info. + * + * @param tableName + * the table name + * @param isIndexable + * the is indexable + * @param tableSchemaType + * the table schema type + * @param idClassType + * the id class type + */ + public TableInfo(String tableName, String tableSchemaType, Class idClassType, String idColumnName) + { + this.tableName = tableName; + this.type = tableSchemaType; + this.idClazz = idClassType; + this.idColumnName = idColumnName; + } + + /** + * Equals method compare two object of TableInfo on the basis of their name + * . + * + * @param obj + * the obj + * @return boolean value. + */ + @Override + public boolean equals(Object obj) + { + + return obj != null && obj instanceof TableInfo && ((TableInfo) obj).tableName != null ? this.tableName != null + && this.tableName.equals(((TableInfo) obj).tableName) : false; + + } + + @Override + /** + * returns the hash code for object. + * + */ + public int hashCode() + { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + /** + * returns the string representation of object . + * + */ + public String toString() + { + StringBuilder strBuilder = new StringBuilder("tableIdType:==> "); + strBuilder.append(idClazz); + strBuilder.append(" | tableName: ==>"); + strBuilder.append(tableName); + strBuilder.append(" | type: ==>"); + strBuilder.append(type); + return strBuilder.toString(); + } + + /** + * Gets the table name. + * + * @return the tableName + */ + public String getTableName() + { + return tableName; + } + + /** + * Sets the table name. + * + * @param tableName + * the tableName to set + */ + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + /** + * Gets the table id type. + * + * @return the tableIdType + */ + public Class getTableIdType() + { + return idClazz; + } + + /** + * Sets the table id type. + * + * @param tableIdType + * the tableIdType to set + */ + public void setTableIdType(Class tableIdType) + { + this.idClazz = tableIdType; + } + + /** + * Gets the column metadatas. + * + * @return the columnMetadatas + */ + public List getColumnMetadatas() + { + + if (this.columnMetadatas == null) + { + this.columnMetadatas = new ArrayList(); + } + + return columnMetadatas; + } + + /** + * Adds the column info. + * + * @param columnInfo + * the column info + */ + public void addColumnInfo(ColumnInfo columnInfo) + { + if (this.columnMetadatas == null) + { + this.columnMetadatas = new ArrayList(); + } + if (!columnMetadatas.contains(columnInfo)) + { + columnMetadatas.add(columnInfo); + } + } + + /** + * Adds the embedded column info. + * + * @param embdColumnInfo + * the embd column info + */ + public void addEmbeddedColumnInfo(EmbeddedColumnInfo embdColumnInfo) + { + if (this.embeddedColumnMetadatas == null) + { + this.embeddedColumnMetadatas = new ArrayList(); + } + if (!embeddedColumnMetadatas.contains(embdColumnInfo)) + { + embeddedColumnMetadatas.add(embdColumnInfo); + } + } + + /** + * Gets the embedded column metadatas. + * + * @return the embeddedColumnMetadatas + */ + public List getEmbeddedColumnMetadatas() + { + if (this.embeddedColumnMetadatas == null) + { + this.embeddedColumnMetadatas = new ArrayList(); + } + return embeddedColumnMetadatas; + } + + /** + * @return the collectionColumnMetadatas + */ + public List getCollectionColumnMetadatas() + { + if(this.collectionColumnMetadatas == null) + { + this.collectionColumnMetadatas = new ArrayList(); + } + return collectionColumnMetadatas; + } + + /** + * @param collectionColumnMetadatas the collectionColumnMetadatas to set + */ + public void addCollectionColumnMetadata(CollectionColumnInfo collectionColumnMetadata) + { + if(this.collectionColumnMetadatas == null) + { + this.collectionColumnMetadatas = new ArrayList(); + } + + if(! collectionColumnMetadatas.contains(collectionColumnMetadata)) + { + collectionColumnMetadatas.add(collectionColumnMetadata); + } + } + + /** + * Gets the type. + * + * @return the type + */ + public String getType() + { + return type; + } + + /** + * Returns name of id attribute. + * + * @return id attribute name. + */ + public String getIdColumnName() + { + return idColumnName; + } + + /** + * Returns list of index information object. + * + * @return + */ + public List getColumnsToBeIndexed() + { + return this.columnToBeIndexed; + } + + public IndexInfo getColumnToBeIndexed(String columnName) + { + IndexInfo idxInfo = new IndexInfo(columnName); + if (columnToBeIndexed.contains(idxInfo)) + { + int index = columnToBeIndexed.indexOf(idxInfo); + return getColumnsToBeIndexed().get(index); + } + return idxInfo; + } + + public void addToIndexedColumnList(IndexInfo indexInfo) + { + ColumnInfo columnInfo = new ColumnInfo(); + columnInfo.setColumnName(indexInfo.getColumnName()); + if (getEmbeddedColumnMetadatas().isEmpty() + || !getEmbeddedColumnMetadatas().get(0).getColumns().contains(columnInfo)) + { + if (!columnToBeIndexed.contains(indexInfo)) + { + columnToBeIndexed.add(indexInfo); + } + } + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/AbstractSchemaManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/AbstractSchemaManager.java new file mode 100644 index 000000000..e3409c7ae --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/AbstractSchemaManager.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure.schema.api; + +import java.util.List; +import java.util.Map; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema; +import com.impetus.kundera.configure.schema.TableInfo; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Abstract Schema Manager has abstract method to handle + * {@code SchemaOperationType}. + * + * @author Kuldeep.Kumar + * + */ +public abstract class AbstractSchemaManager +{ + + /** The pu metadata variable. */ + protected PersistenceUnitMetadata puMetadata; + + /** The port variable. */ + protected String port; + + /** The host variable . */ + protected String[] hosts; + + /** The kundera_client variable. */ + protected String clientFactory; + + /** The database name variable. */ + protected String databaseName; + + /** The table infos variable . */ + protected List tableInfos; + + /** The operation variable. */ + protected String operation; + + protected List schemas = null; + + protected Connection conn = null; + + protected DataStore dataStore = null; + + protected Map externalProperties; + + /** + * Initialise with configured client factory. + * + * @param clientFactory + * specific client factory. + * @param externalProperties + */ + protected AbstractSchemaManager(String clientFactory, Map externalProperties) + { + this.clientFactory = clientFactory; + this.externalProperties = externalProperties; + } + + /** + * Export schema handles the handleOperation method. + * + * @param hbase + */ + protected void exportSchema(final String persistenceUnit, List tables) + { + // Get persistence unit metadata + PersistenceUnitMetadata puMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit); + String paramString = externalProperties != null ? (String) externalProperties + .get(PersistenceProperties.KUNDERA_CLIENT_FACTORY) : null; + if (clientFactory != null + && ((clientFactory.equalsIgnoreCase(puMetadata.getProperties().getProperty( + PersistenceProperties.KUNDERA_CLIENT_FACTORY))) || (paramString != null && clientFactory + .equalsIgnoreCase(paramString)))) + { + readConfigProperties(puMetadata); + + // invoke handle operation. + if (operation != null && initiateClient()) + { + tableInfos = tables; + handleOperations(tables); + } + } + } + + /** + * @param pu + */ + private void readConfigProperties(final PersistenceUnitMetadata puMetadata) + { + String hostName = null; + String portName = null; + String operationType = null; + String schemaName = null; + if (externalProperties != null) + { + portName = (String) externalProperties.get(PersistenceProperties.KUNDERA_PORT); + hostName = (String) externalProperties.get(PersistenceProperties.KUNDERA_NODES); + schemaName = (String) externalProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + // get type of schema of operation. + operationType = (String) externalProperties.get(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE); + } + if (portName == null) + portName = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_PORT); + if (hostName == null) + hostName = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_NODES); + if (schemaName == null) + schemaName = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_KEYSPACE); + // get type of schema of operation. + if (operationType == null) + operationType = puMetadata.getProperty(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE); + + String[] hostArray = hostName.split(","); + hosts = new String[hostArray.length]; + for (int i = 0; i < hostArray.length; i++) + { + hosts[i] = hostArray[i].trim(); + } + this.port = portName; + this.databaseName = schemaName; + this.operation = operationType; + } + + /** + * Initiate client to initialize with client specific schema. + * + * @return true, if successful + */ + protected abstract boolean initiateClient(); + + /** + * Validates the schema. + * + * @param tableInfos + * the table infos + */ + protected abstract void validate(List tableInfos); + + /** + * Update. + * + * @param tableInfos + * the table infos + */ + protected abstract void update(List tableInfos); + + /** + * Creates the. + * + * @param tableInfos + * the table infos + */ + protected abstract void create(List tableInfos); + + /** + * Create_drop. + * + * @param tableInfos + * the table infos + */ + protected abstract void create_drop(List tableInfos); + + /** + * handleOperations method handles the all operation on the basis of + * operationType + */ + + /** + * enum class for operation type + */ + /** + * The Enum ScheamOperationType. + */ + public enum SchemaOperationType + { + + /** The createdrop. */ + createdrop, + /** The create. */ + create, + /** The validate. */ + validate, + /** The update. */ + update; + + /** + * Gets the single instance of ScheamOperationType. + * + * @param operation + * the operation + * @return single instance of ScheamOperationType + */ + public static SchemaOperationType getInstance(String operation) + { + if (operation.equalsIgnoreCase("create-drop")) + { + return SchemaOperationType.createdrop; + } + return SchemaOperationType.valueOf(SchemaOperationType.class, operation); + } + } + + /** + * Handle operations. + * + * @param tableInfos + * the table infos + */ + private void handleOperations(List tableInfos) + { + SchemaOperationType operationType = SchemaOperationType.getInstance(operation); + + switch (operationType) + { + case createdrop: + create_drop(tableInfos); + break; + case create: + create(tableInfos); + break; + case update: + update(tableInfos); + break; + case validate: + validate(tableInfos); + break; + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/SchemaManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/SchemaManager.java new file mode 100644 index 000000000..8414607d3 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/configure/schema/api/SchemaManager.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.configure.schema.api; + +import java.util.List; +import java.util.Map; + +import com.impetus.kundera.configure.schema.TableInfo; + +/** + * Interface to define methods to be implemented by different schema managers. + * + * @author kuldeep.kumar + * + */ +public interface SchemaManager +{ + /** + * Exports schema according to configured schema operation e.g. + * {create,create-drop,update,validate} + */ + void exportSchema(String persistenceUnit, List puToSchemaCol); + + /** + * Method required to drop auto create schema,in case of schema operation as + * {create-drop}, + */ + void dropSchema(); + + /** + * validates the entity against the Client specific properties. + * + * @return + * + */ + boolean validateEntity(Class clazz); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/db/DataRow.java b/src/kundera-core/src/main/java/com/impetus/kundera/db/DataRow.java new file mode 100644 index 000000000..d27627b8a --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/db/DataRow.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.db; + +import java.util.ArrayList; +import java.util.List; + +/** + * Utility class that represents a row in Column family based datastores like + * cassandra and HBase. + * + * @param + * the generic type + * @author amresh.singh + */ +public class DataRow +{ + /** Id of the row. */ + private String id; + + /** name of the family. */ + private String columnFamilyName; + + /** list of thrift columns from the row. */ + private List columns; + + /** + * default constructor. + */ + public DataRow() + { + columns = new ArrayList(); + } + + /** + * The Constructor. + * + * @param id + * the id + * @param columnFamilyName + * the column family name + * @param columns + * the columns + */ + public DataRow(String id, String columnFamilyName, List columns) + { + this.id = id; + this.columnFamilyName = columnFamilyName; + this.columns = columns; + } + + /** + * Gets the id. + * + * @return the id + */ + public String getId() + { + return id; + } + + /** + * Gets the column family name. + * + * @return the columnFamilyName + */ + public String getColumnFamilyName() + { + return columnFamilyName; + } + + /** + * Gets the columns. + * + * @return the columns + */ + public List getColumns() + { + return columns; + } + + /** + * Adds the column.; + * + * @param column + * the column + */ + public void addColumn(TF column) + { + columns.add(column); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/db/RelationHolder.java b/src/kundera-core/src/main/java/com/impetus/kundera/db/RelationHolder.java new file mode 100644 index 000000000..be43e7642 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/db/RelationHolder.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.db; + +/** + * The Class RelationHolder. + * + * @author vivek.mishra + */ +public class RelationHolder +{ + + /** The relation name. */ + private String relationName; + + /** The relation value. */ + private Object relationValue; + + /** Holds object through which this relation is maintained */ + private Object relationVia; + + /** + * Instantiates a new relation holder. + * + * @param relationName + * the relation name + * @param relationValue + * the relation value + */ + public RelationHolder(String relationName, Object relationValue) + { + this.relationName = relationName; + this.relationValue = relationValue; + } + + public RelationHolder(String relationName, Object relationValue, Object relationVia) + { + this.relationName = relationName; + this.relationValue = relationValue; + this.relationVia = relationVia; + } + + /** + * Gets the relation name. + * + * @return the relationName + */ + public String getRelationName() + { + return relationName; + } + + /** + * Gets the relation value. + * + * @return the relationValue + */ + public Object getRelationValue() + { + return relationValue; + } + + /** + * @return the relationVia + */ + public Object getRelationVia() + { + return relationVia; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/db/SearchResult.java b/src/kundera-core/src/main/java/com/impetus/kundera/db/SearchResult.java new file mode 100644 index 000000000..6fd80e0d9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/db/SearchResult.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.db; + +import java.util.ArrayList; +import java.util.List; + +/** + * Holds High level search result info from database records + * + * @author amresh + * + */ +public class SearchResult +{ + private Object primaryKey; + + private String embeddedColumnName; + + private List embeddedColumnValues; + + /** + * @return the primaryKey + */ + public Object getPrimaryKey() + { + return primaryKey; + } + + /** + * @param primaryKey + * the primaryKey to set + */ + public void setPrimaryKey(Object primaryKey) + { + this.primaryKey = primaryKey; + } + + /** + * @return the embeddedColumnName + */ + public String getEmbeddedColumnName() + { + return embeddedColumnName; + } + + /** + * @param embeddedColumnName + * the embeddedColumnName to set + */ + public void setEmbeddedColumnName(String embeddedColumnName) + { + this.embeddedColumnName = embeddedColumnName; + } + + /** + * @return the embeddedColumnValues + */ + public List getEmbeddedColumnValues() + { + return embeddedColumnValues; + } + + /** + * @param embeddedColumnValues + * the embeddedColumnValues to set + */ + public void addEmbeddedColumnValue(String embeddedColumnValue) + { + if (embeddedColumnValues == null) + { + embeddedColumnValues = new ArrayList(); + } + embeddedColumnValues.add(embeddedColumnValue); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/generator/AutoGenerator.java b/src/kundera-core/src/main/java/com/impetus/kundera/generator/AutoGenerator.java new file mode 100644 index 000000000..e98efd775 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/generator/AutoGenerator.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.generator; + +/** + * {@link AutoGenerator} interface , all client should implement this interface + * in order to support auto generation strategy. + * + * @author Kuldeep.Mishra + * + */ +public interface AutoGenerator extends Generator +{ + /** + * generate id, Its totally client responsibility to generate Id, using + * client specific strategy. + * + * @param discriptor + * @return + */ + public Object generate(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/generator/Generator.java b/src/kundera-core/src/main/java/com/impetus/kundera/generator/Generator.java new file mode 100644 index 000000000..0ff11c679 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/generator/Generator.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.generator; + +/** + * Generator Interface implemented by all generator. + * + * @author Kuldeep.Mishra + * + */ +public interface Generator +{ + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/generator/IdentityGenerator.java b/src/kundera-core/src/main/java/com/impetus/kundera/generator/IdentityGenerator.java new file mode 100644 index 000000000..891788242 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/generator/IdentityGenerator.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.generator; + +import com.impetus.kundera.metadata.model.SequenceGeneratorDiscriptor; + +/** + * {@link IdentityGenerator} interface , all client should implement this + * interface in order to support identity generation strategy. + * + * @author Kuldeep.Mishra + * + */ +public interface IdentityGenerator extends Generator +{ + /** + * generate id on the basis of {@SequenceGeneratorDiscriptor + * + * } property. + * + * @param discriptor + * @return + */ + public Object generate(SequenceGeneratorDiscriptor discriptor); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/generator/SequenceGenerator.java b/src/kundera-core/src/main/java/com/impetus/kundera/generator/SequenceGenerator.java new file mode 100644 index 000000000..ab4ddf8b7 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/generator/SequenceGenerator.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.generator; + +import com.impetus.kundera.metadata.model.SequenceGeneratorDiscriptor; + +/** + * {@link SequenceGenerator} interface , all client should implement this + * interface in order to support sequence generation strategy. + * + * @author Kuldeep.Mishra + * + */ +public interface SequenceGenerator extends Generator +{ + /** + * generate id on the basis of {@SequenceGeneratorDiscriptor + * + * } property. + * + * @param discriptor + * @return + */ + public Object generate(SequenceGeneratorDiscriptor discriptor); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/generator/TableGenerator.java b/src/kundera-core/src/main/java/com/impetus/kundera/generator/TableGenerator.java new file mode 100644 index 000000000..9a61373f3 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/generator/TableGenerator.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.generator; + +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; + +/** + * {@link TableGenerator} interface , all client should implement this interface + * in order to support table generation strategy. + * + * @author Kuldeep.Mishra + * + */ +public interface TableGenerator extends Generator +{ + /** + * generate id on the basis of {@TableGeneratorDiscriptor + * + * + * } property. + * + * @param discriptor + * @return + */ + public Object generate(TableGeneratorDiscriptor discriptor); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/SurfaceType.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/SurfaceType.java new file mode 100644 index 000000000..ac9dc7fb3 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/SurfaceType.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.gis; + +/** + * @author amresh + * + */ +public enum SurfaceType +{ + FLAT, SPHERICAL; +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Circle.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Circle.java new file mode 100644 index 000000000..6e4974b52 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Circle.java @@ -0,0 +1,97 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +import com.impetus.kundera.gis.SurfaceType; + +/** + * Geometric class representing circle shape + * + * @author amresh.singh + */ +public class Circle +{ + private Coordinate centre; + + private double radius; + + /** Surface type on which this circle is based */ + private SurfaceType surfaceType = SurfaceType.FLAT; + + public Circle(double x, double y, double r) + { + setCentre(new Coordinate(x, y)); + setRadius(r); + } + + public Circle(Coordinate centre, double radius) + { + this.centre = centre; + this.radius = radius; + } + + /** + * @return the centre + */ + public Coordinate getCentre() + { + return centre; + } + + /** + * @param centre + * the centre to set + */ + public void setCentre(Coordinate centre) + { + this.centre = centre; + } + + /** + * @return the radius + */ + public double getRadius() + { + return radius; + } + + /** + * @param radius + * the radius to set + */ + public void setRadius(double radius) + { + this.radius = radius; + } + + /** + * @return the surfaceType + */ + public SurfaceType getSurfaceType() + { + return surfaceType; + } + + /** + * @param surfaceType + * the surfaceType to set + */ + public void setSurfaceType(SurfaceType surfaceType) + { + this.surfaceType = surfaceType; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Coordinate.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Coordinate.java new file mode 100644 index 000000000..5b62f3559 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Coordinate.java @@ -0,0 +1,64 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +/** + * Geometric Coordinate implementation + * + * @author amresh.singh + */ +public class Coordinate extends com.vividsolutions.jts.geom.Coordinate +{ + /** + * + */ + public Coordinate() + { + super(); + + } + + /** + * @param c + */ + public Coordinate(com.vividsolutions.jts.geom.Coordinate c) + { + super(c); + + } + + /** + * @param x + * @param y + * @param z + */ + public Coordinate(double x, double y, double z) + { + super(x, y, z); + + } + + /** + * @param x + * @param y + */ + public Coordinate(double x, double y) + { + super(x, y); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Envelope.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Envelope.java new file mode 100644 index 000000000..0138d8dbb --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Envelope.java @@ -0,0 +1,75 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Geometric Envelope (Box) implementation + * + * @author amresh.singh + */ +public class Envelope extends com.vividsolutions.jts.geom.Envelope +{ + + /** + * + */ + public Envelope() + { + } + + /** + * @param p + */ + public Envelope(Coordinate p) + { + super(p); + + } + + /** + * @param env + */ + public Envelope(com.vividsolutions.jts.geom.Envelope env) + { + super(env); + + } + + /** + * @param p1 + * @param p2 + */ + public Envelope(Coordinate p1, Coordinate p2) + { + super(p1, p2); + + } + + /** + * @param x1 + * @param x2 + * @param y1 + * @param y2 + */ + public Envelope(double x1, double x2, double y1, double y2) + { + super(x1, x2, y1, y2); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Point.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Point.java new file mode 100644 index 000000000..984810484 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Point.java @@ -0,0 +1,82 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +import com.impetus.kundera.gis.SurfaceType; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.CoordinateSequence; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.PrecisionModel; + +/** + * Geometric Point implementation + * + * @author amresh.singh + */ +public class Point extends com.vividsolutions.jts.geom.Point +{ + /** Surface type on which this point is based */ + private SurfaceType surfaceType = SurfaceType.FLAT; + + public Point(com.vividsolutions.jts.geom.Point point) + { + super(point.getCoordinate(), point.getPrecisionModel(), point.getSRID()); + } + + public Point(double x, double y) + { + super(new Coordinate(x, y), new PrecisionModel(), 0); + } + + /** + * @param coordinates + * @param factory + */ + public Point(CoordinateSequence coordinates, GeometryFactory factory) + { + super(coordinates, factory); + } + + /** + * @param coordinate + * @param precisionModel + * @param SRID + * @deprecated + */ + public Point(Coordinate coordinate, PrecisionModel precisionModel, int SRID) + { + super(coordinate, precisionModel, SRID); + + } + + /** + * @return the surfaceType + */ + public SurfaceType getSurfaceType() + { + return surfaceType; + } + + /** + * @param surfaceType + * the surfaceType to set + */ + public void setSurfaceType(SurfaceType surfaceType) + { + this.surfaceType = surfaceType; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Polygon.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Polygon.java new file mode 100644 index 000000000..cc3fea9a7 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Polygon.java @@ -0,0 +1,54 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; + +/** + * Geometric Polygon implementation + * + * @author amresh.singh + */ +public class Polygon extends com.vividsolutions.jts.geom.Polygon +{ + + /** + * @param shell + * @param holes + * @param factory + */ + public Polygon(LinearRing shell, LinearRing[] holes, GeometryFactory factory) + { + super(shell, holes, factory); + } + + @Override + public Coordinate[] getCoordinates() + { + com.vividsolutions.jts.geom.Coordinate[] coordinates = super.getCoordinates(); + + Coordinate[] cs = new Coordinate[coordinates.length]; + + int count = 0; + for (com.vividsolutions.jts.geom.Coordinate c : coordinates) + { + cs[count++] = new Coordinate(c); + } + + return cs; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Triangle.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Triangle.java new file mode 100644 index 000000000..956411b2c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/geometry/Triangle.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.geometry; + +/** + * Geometric Triangle implementation + * + * @author amresh.singh + */ +public class Triangle extends com.vividsolutions.jts.geom.Triangle +{ + + public Triangle(double x1, double y1, double x2, double y2, double x3, double y3) + { + super(new Coordinate(x1, y1), new Coordinate(x2, y2), new Coordinate(x3, y3)); + } + + /** + * @param p0 + * @param p1 + * @param p2 + */ + public Triangle(Coordinate p0, Coordinate p1, Coordinate p2) + { + super(p0, p1, p2); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/gis/query/GeospatialQuery.java b/src/kundera-core/src/main/java/com/impetus/kundera/gis/query/GeospatialQuery.java new file mode 100644 index 000000000..e1c89f9c7 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/gis/query/GeospatialQuery.java @@ -0,0 +1,27 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.gis.query; + +/** + * Provides methods related to Geospatial Queries + * + * @author amresh.singh + */ +public interface GeospatialQuery +{ + Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/graph/Node.java b/src/kundera-core/src/main/java/com/impetus/kundera/graph/Node.java new file mode 100644 index 000000000..d2133543c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/graph/Node.java @@ -0,0 +1,765 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.graph; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.PostPersist; +import javax.persistence.PostRemove; +import javax.persistence.PostUpdate; +import javax.persistence.PrePersist; +import javax.persistence.PreRemove; +import javax.persistence.PreUpdate; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.graph.NodeLink.LinkProperty; +import com.impetus.kundera.lifecycle.NodeStateContext; +import com.impetus.kundera.lifecycle.states.NodeState; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.lifecycle.states.TransientState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.persistence.context.PersistenceCache; +import com.impetus.kundera.persistence.event.EntityEventDispatcher; +import com.impetus.kundera.utils.ObjectUtils; + +/** + * Represents a node in object graph + * + * @author amresh.singh + */ +public class Node implements NodeStateContext +{ + + // ID of a node into object graph + private String nodeId; + + // Primary key of entity data contained in this node + private Object entityId; + + // Actual node data + private Object data; + + // Current node state as defined in state machine + private NodeState currentNodeState; + + // Class of actual node data + private Class dataClass; + + // All parents of this node, Key is Node Link info and value is node itself + private Map parents; + + // All children of this node, Key is Node Link info and value is node itself + private Map children; + + // Whether this node has been traversed + private boolean traversed; + + // Whether this node is dirty + private boolean dirty; + + // Whether this node for update. + private boolean isUpdate; + + /* + * Depth of this node in the tree Head node has a depth of 1 and so on. + */ + private int depth; + + /** Client for this node */ + private Client client; + + // Reference to Persistence cache where this node is stored + private PersistenceCache persistenceCache; + + // Whether graph is completely traversed or not. + private boolean isGraphCompleted; + + private PersistenceDelegator pd; + + private Node originalNode; + + private boolean isProcessed; + + private EntityEventDispatcher eventDispatcher = new EntityEventDispatcher(); + + private Node(String nodeId, Object data, PersistenceCache pc, Object primaryKey) + { + initializeNode(nodeId, data, primaryKey); + setPersistenceCache(pc); + + // Initialize current node state to transient state + this.currentNodeState = new TransientState(); + } + + Node(String nodeId, Object data, NodeState initialNodeState, PersistenceCache pc, Object primaryKey) + { + initializeNode(nodeId, data, primaryKey); + setPersistenceCache(pc); + + // Initialize current node state + if (initialNodeState == null) + { + this.currentNodeState = new TransientState(); + } + else + { + this.currentNodeState = initialNodeState; + } + } + + public Node(String nodeId, Class nodeDataClass, NodeState initialNodeState, PersistenceCache pc, + Object primaryKey) + { + this.nodeId = nodeId; + this.dataClass = nodeDataClass; + this.entityId = primaryKey; + setPersistenceCache(pc); + + // Initialize current node state + if (initialNodeState == null) + { + this.currentNodeState = new TransientState(); + } + else + { + this.currentNodeState = initialNodeState; + } + } + + private void initializeNode(String nodeId, Object data, Object primaryKey) + { + this.nodeId = nodeId; + this.data = data; + this.dataClass = data != null ? data.getClass() : null; + this.dirty = true; + this.entityId = primaryKey; + } + + /** + * @return the nodeId + */ + @Override + public String getNodeId() + { + return nodeId; + } + + /** + * @param nodeId + * the nodeId to set + */ + @Override + public void setNodeId(String nodeId) + { + this.nodeId = nodeId; + } + + /** + * @return the data + */ + @Override + public Object getData() + { + return data; + } + + /** + * @param data + * the data to set + */ + @Override + public void setData(Object data) + { + this.data = data; + } + + /** + * @return the dataClass + */ + @Override + public Class getDataClass() + { + return dataClass; + } + + /** + * @param dataClass + * the dataClass to set + */ + @Override + public void setDataClass(Class dataClass) + { + this.dataClass = dataClass; + } + + /** + * @return the currentNodeState + */ + @Override + public NodeState getCurrentNodeState() + { + return currentNodeState; + } + + /** + * @param currentNodeState + * the currentNodeState to set + */ + @Override + public void setCurrentNodeState(NodeState currentNodeState) + { + this.currentNodeState = currentNodeState; + } + + /** + * @return the parents + */ + @Override + public Map getParents() + { + return parents; + } + + /** + * @param parents + * the parents to set + */ + @Override + public void setParents(Map parents) + { + this.parents = parents; + } + + /** + * @return the children + */ + @Override + public Map getChildren() + { + return children; + } + + /** + * @param children + * the children to set + */ + @Override + public void setChildren(Map children) + { + this.children = children; + } + + /** + * @return the isHeadNode + */ + public boolean isHeadNode() + { + return this != null && this.parents == null ? true : false; + } + + /** + * Retrieves parent node of this node for a given parent node ID + */ + @Override + public Node getParentNode(String parentNodeId) + { + NodeLink link = new NodeLink(parentNodeId, getNodeId()); + + if (this.parents == null) + { + return null; + } + else + { + return this.parents.get(link); + } + } + + /** + * Retrieves child node of this node for a given child node ID + */ + + @Override + public Node getChildNode(String childNodeId) + { + NodeLink link = new NodeLink(getNodeId(), childNodeId); + + if (this.children == null) + { + return null; + } + else + { + return this.children.get(link); + } + } + + @Override + public void addParentNode(NodeLink nodeLink, Node node) + { + if (parents == null || parents.isEmpty()) + { + parents = new HashMap(); + } + parents.put(nodeLink, node); + } + + @Override + public void addChildNode(NodeLink nodeLink, Node node) + { + if (children == null || children.isEmpty()) + { + children = new HashMap(); + } + children.put(nodeLink, node); + } + + /** + * @return the traversed + */ + @Override + public boolean isTraversed() + { + return traversed; + } + + /** + * @param traversed + * the traversed to set + */ + @Override + public void setTraversed(boolean traversed) + { + this.traversed = traversed; + } + + /** + * @return the dirty + */ + @Override + public boolean isDirty() + { + return dirty; + } + + /** + * @param dirty + * the dirty to set + */ + @Override + public void setDirty(boolean dirty) + { + this.dirty = dirty; + } + + /** + * @return the client + */ + @Override + public Client getClient() + { + return client; + } + + /** + * @param client + * the client to set + */ + + @Override + public void setClient(Client client) + { + this.client = client; + } + + @Override + public PersistenceDelegator getPersistenceDelegator() + { + return pd; + } + + @Override + public void setPersistenceDelegator(PersistenceDelegator pd) + { + this.pd = pd; + } + + @Override + public String toString() + { + return "[" + nodeId + "]" + nodeId; + } + + @Override + public boolean equals(Object otherNode) + { + if (otherNode == null) + { + return false; + } + + if (!(otherNode instanceof Node)) + { + return false; + } + + return this.nodeId.equals(((Node) otherNode).getNodeId()); + } + + @Override + public int hashCode() + { + return HashCodeBuilder.reflectionHashCode(this.nodeId); + } + + // //////////////////////////////////////// + /* CRUD related operations on this node */ + // //////////////////////////////////////// + + @Override + public void persist() + { + getCurrentNodeState().handlePersist(this); + } + + @Override + public void remove() + { + getCurrentNodeState().handleRemove(this); + } + + @Override + public void refresh() + { + getCurrentNodeState().handleRefresh(this); + } + + @Override + public void merge() + { + getCurrentNodeState().handleMerge(this); + } + + @Override + public void detach() + { + getCurrentNodeState().handleDetach(this); + } + + @Override + public void close() + { + getCurrentNodeState().handleClose(this); + } + + @Override + public void lock() + { + getCurrentNodeState().handleLock(this); + } + + @Override + public void commit() + { + getCurrentNodeState().handleCommit(this); + } + + @Override + public void rollback() + { + getCurrentNodeState().handleRollback(this); + } + + @Override + public void find() + { + getCurrentNodeState().handleFind(this); + } + + @Override + public void getReference() + { + getCurrentNodeState().handleGetReference(this); + } + + @Override + public void contains() + { + getCurrentNodeState().handleContains(this); + } + + @Override + public void clear() + { + getCurrentNodeState().handleClear(this); + } + + @Override + public void flush() + { + if (isDirty()) + { + handlePreEvent(); + getCurrentNodeState().handleFlush(this); + handlePostEvent(); + this.isProcessed = true; + } + + // Update Link value for all nodes attached to this one + Map parents = this.getParents(); + Map children = this.getChildren(); + + // update links. + if (parents != null && !parents.isEmpty()) + { + for (NodeLink parentNodeLink : parents.keySet()) + { + if (!parentNodeLink.getMultiplicity().equals(ForeignKey.MANY_TO_MANY)) + parentNodeLink.addLinkProperty(LinkProperty.LINK_VALUE, this.getEntityId()); + } + } + + if (children != null && !children.isEmpty()) + { + for (NodeLink childNodeLink : children.keySet()) + { + if (!childNodeLink.getMultiplicity().equals(ForeignKey.MANY_TO_MANY)) + childNodeLink.addLinkProperty(LinkProperty.LINK_VALUE, this.getEntityId()); + } + } + } + + // Overridden methods from + + @Override + public boolean isInState(Class stateClass) + { + return getCurrentNodeState().getClass().equals(stateClass); + } + + @Override + public PersistenceCache getPersistenceCache() + { + return this.persistenceCache; + } + + @Override + public void setPersistenceCache(PersistenceCache persistenceCache) + { + this.persistenceCache = persistenceCache; + } + + /** + * @return the isGraphCompleted + */ + boolean isGraphCompleted() + { + return isGraphCompleted; + } + + /** + * @param isGraphCompleted + * the isGraphCompleted to set + */ + void setGraphCompleted(boolean isGraphCompleted) + { + this.isGraphCompleted = isGraphCompleted; + } + + /** + * @return the originalNode + */ + public Node getOriginalNode() + { + return originalNode; + } + + /** + * @param originalNode + * the originalNode to set + */ + public void setOriginalNode(Node originalNode) + { + this.originalNode = originalNode; + } + + /** + * @return the isProcessed + */ + public boolean isProcessed() + { + return isProcessed; + } + + /** + * @return the isUpdate + */ + public boolean isUpdate() + { + return isUpdate; + } + + /** + * @param isUpdate + * the isUpdate to set + */ + public void setUpdate(boolean isUpdate) + { + this.isUpdate = isUpdate; + } + + @Override + public Node clone() + { + Node cloneCopy = new Node(this.nodeId, ObjectUtils.deepCopy(this.getData()), this.persistenceCache, + this.entityId); + cloneCopy.setChildren(this.children); + cloneCopy.setParents(this.parents); + cloneCopy.setDataClass(this.dataClass); + cloneCopy.setTraversed(this.traversed); + + return cloneCopy; + } + + @Override + public Object getEntityId() + { + return this.entityId; + } + + public void setEntityId(Object id) + { + this.entityId = id; + } + + public void handlePreEvent() + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(this.getDataClass()); + + if (isUpdate) + { + onPreEvent(metadata, EntityEvent.UPDATE); + } + else if (this.isInState(RemovedState.class)) + { + onPreEvent(metadata, EntityEvent.REMOVE); + } + else + { + onPreEvent(metadata, EntityEvent.PERSIST); + } + } + + public void handlePostEvent() + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(this.getDataClass()); + + if (isUpdate) + { + onPostEvent(metadata, EntityEvent.UPDATE); + } + else if (this.isInState(RemovedState.class)) + { + onPostEvent(metadata, EntityEvent.REMOVE); + } + else + { + onPostEvent(metadata, EntityEvent.PERSIST); + } + } + + private void onPreEvent(EntityMetadata metadata, EntityEvent event) + { + try + { + this.eventDispatcher.fireEventListeners(metadata, this.data, EntityEvent.getPreEvent(event)); + } + catch (Exception es) + { + throw new KunderaException(es); + } + } + + private void onPostEvent(EntityMetadata metadata, EntityEvent event) + { + try + { + this.eventDispatcher.fireEventListeners(metadata, this.data, EntityEvent.getPostEvent(event)); + } + catch (Exception es) + { + throw new KunderaException(es); + } + } + + private enum EntityEvent + { + UPDATE, PERSIST, REMOVE; + + private final static Class getPreEvent(EntityEvent event) + { + Class clazz = null; + switch (event) + { + case PERSIST: + clazz = PrePersist.class; + break; + + case UPDATE: + clazz = PreUpdate.class; + break; + + case REMOVE: + clazz = PreRemove.class; + break; + + default: + // TODO: Throw an error. + } + return clazz; + } + + private final static Class getPostEvent(EntityEvent event) + { + Class clazz = null; + switch (event) + { + case PERSIST: + clazz = PostPersist.class; + break; + + case UPDATE: + clazz = PostUpdate.class; + break; + + case REMOVE: + clazz = PostRemove.class; + break; + + default: + // TODO: Throw an error. + } + return clazz; + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/graph/NodeLink.java b/src/kundera-core/src/main/java/com/impetus/kundera/graph/NodeLink.java new file mode 100644 index 000000000..905db3891 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/graph/NodeLink.java @@ -0,0 +1,189 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.graph; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.builder.EqualsBuilder; + +import com.impetus.kundera.metadata.model.Relation; + +/** + * Holds link meta data for a unidirectional directed link from source node to + * target node. + * + * @author amresh.singh + */ +public class NodeLink +{ + // All possible node link properties + public enum LinkProperty + { + LINK_NAME, LINK_VALUE, IS_SHARED_BY_PRIMARY_KEY, IS_BIDIRECTIONAL, IS_RELATED_VIA_JOIN_TABLE, PROPERTY, BIDIRECTIONAL_PROPERTY, CASCADE, JOIN_TABLE_METADATA + // Add more if required + }; + + private String sourceNodeId; + + private String targetNodeId; + + // Multiplicity of relationship + private Relation.ForeignKey multiplicity; + + // Contains all properties for this link + private Map linkProperties; + + public NodeLink() + { + + } + + public NodeLink(String sourceNodeId, String targetNodeId) + { + this.sourceNodeId = sourceNodeId; + this.targetNodeId = targetNodeId; + } + + /** + * @return the sourceNodeId + */ + public String getSourceNodeId() + { + return sourceNodeId; + } + + /** + * @param sourceNodeId + * the sourceNodeId to set + */ + public void setSourceNodeId(String sourceNodeId) + { + this.sourceNodeId = sourceNodeId; + } + + /** + * @return the targetNodeId + */ + public String getTargetNodeId() + { + return targetNodeId; + } + + /** + * @param targetNodeId + * the targetNodeId to set + */ + public void setTargetNodeId(String targetNodeId) + { + this.targetNodeId = targetNodeId; + } + + /** + * @return the multiplicity + */ + public Relation.ForeignKey getMultiplicity() + { + return multiplicity; + } + + /** + * @param multiplicity + * the multiplicity to set + */ + public void setMultiplicity(Relation.ForeignKey multiplicity) + { + this.multiplicity = multiplicity; + } + + /** + * @return the linkProperties + */ + public Map getLinkProperties() + { + return linkProperties; + } + + /** + * @param linkProperties + * the linkProperties to set + */ + public void setLinkProperties(Map linkProperties) + { + this.linkProperties = linkProperties; + } + + /** + * @return the linkProperties + */ + public Object getLinkProperty(LinkProperty name) + { + if (linkProperties == null || linkProperties.isEmpty()) + { + throw new IllegalStateException("Link properties not initialized"); + } + + return linkProperties.get(name); + } + + public void addLinkProperty(LinkProperty name, Object propertyValue) + { + if (linkProperties == null) + { + linkProperties = new HashMap(); + } + + linkProperties.put(name, propertyValue); + } + + @Override + public int hashCode() + { + int n = getSourceNodeId().hashCode() * getTargetNodeId().hashCode(); + return n; + + // return new + // HashCodeBuilder().append(getSourceNodeId()).append(getTargetNodeId()).hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + + if (!(obj instanceof NodeLink)) + { + return false; + } + + NodeLink targetNodeLink = (NodeLink) obj; + + return new EqualsBuilder().append(getSourceNodeId(), targetNodeLink.getSourceNodeId()) + .append(getTargetNodeId(), targetNodeLink.getTargetNodeId()).isEquals(); + // return getSourceNodeId().equals(targetNodeLink.getSourceNodeId()) + // && getTargetNodeId().equals(targetNodeLink.getTargetNodeId()); + } + + @Override + public String toString() + { + return sourceNodeId + "---(" + multiplicity + ")--->" + targetNodeId; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraph.java b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraph.java new file mode 100644 index 000000000..e6db476d4 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraph.java @@ -0,0 +1,96 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.graph; + +import java.util.HashMap; +import java.util.Map; + +/** + * Holds graph of an object + * + * @author amresh.singh + */ +public class ObjectGraph +{ + // Head node in this object graph + private Node headNode; + + // Mapping between Node ID and Node itself + // Each node contains link to parent/ child nodes it is related to + private Map nodeMapping; + + ObjectGraph() + { + clear(); + nodeMapping = new HashMap(); + } + + /** + * Adds a {@link Node} with a give nodeId to object graph. + * + * @param nodeId + * @param node + */ + public void addNode(String nodeId, Node node) + { + nodeMapping.put(nodeId, node); + } + + /** + * Returns Node for a given node ID + * + * @param nodeId + * @return + */ + Node getNode(String nodeId) + { + return nodeMapping.get(nodeId); + } + + /** + * @return the headNode + */ + public Node getHeadNode() + { + return headNode; + } + + /** + * @param headNode + * the headNode to set + */ + void setHeadNode(Node headNode) + { + this.headNode = headNode; + } + + /** + * @return the nodeMapping + */ + public Map getNodeMapping() + { + return nodeMapping; + } + + public void clear() + { + if (nodeMapping != null) + { + nodeMapping.clear(); + nodeMapping = null; + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphBuilder.java b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphBuilder.java new file mode 100644 index 000000000..195c9ff07 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphBuilder.java @@ -0,0 +1,330 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.graph; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.persistence.MapKeyJoinColumn; + +import org.apache.commons.lang.StringUtils; + +import com.impetus.kundera.graph.NodeLink.LinkProperty; +import com.impetus.kundera.lifecycle.states.NodeState; +import com.impetus.kundera.lifecycle.states.TransientState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.persistence.IdGenerator; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.persistence.PersistenceValidator; +import com.impetus.kundera.persistence.context.PersistenceCache; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.proxy.KunderaProxy; +import com.impetus.kundera.proxy.ProxyHelper; +import com.impetus.kundera.proxy.collection.ProxyCollection; +import com.impetus.kundera.utils.DeepEquals; + +/** + * Responsible for generating {@link ObjectGraph} of nodes from a given entity + * + * @author amresh.singh + */ +public class ObjectGraphBuilder +{ + private PersistenceCache persistenceCache; + + private PersistenceDelegator pd; + + private IdGenerator idGenerator; + + private PersistenceValidator validator; + + public ObjectGraphBuilder(PersistenceCache pcCache, PersistenceDelegator pd) + { + this.persistenceCache = pcCache; + this.pd = pd; + this.idGenerator = new IdGenerator(); + this.validator = new PersistenceValidator(); + } + + public ObjectGraph getObjectGraph(Object entity, NodeState initialNodeState) + { + // Initialize object graph + ObjectGraph objectGraph = new ObjectGraph(); + + // Recursively build object graph and get head node. + Node headNode = getNode(entity, objectGraph, initialNodeState); + + // Set head node into object graph + if (headNode != null) + { + objectGraph.setHeadNode(headNode); + } + return objectGraph; + } + + /** + * Constructs and returns {@link Node} representation for a given entity + * object. Output is fully constructed graph with relationships embedded. + * Each node is put into graph once it is constructed. + * + * @param entity + * @return + */ + private Node getNode(Object entity, ObjectGraph graph, NodeState initialNodeState) + { + + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + + // entity metadata could be null. + if (entityMetadata == null) + { + throw new IllegalArgumentException( + "Entity object is invalid, operation failed. Please check previous log message for details"); + } + + // Generate and set Id if @GeneratedValue present. + + if (initialNodeState != null && initialNodeState.getClass().equals(TransientState.class)) + { + Object id = PropertyAccessorHelper.getId(entity, entityMetadata); + Node nodeInPersistenceCache = null; + if (id != null) + { + String nodeId = ObjectGraphUtils.getNodeId(id, entity.getClass()); + nodeInPersistenceCache = persistenceCache.getMainCache().getNodeFromCache(nodeId); + } + // if node not in persistence cache it means it came first time + // for persist, then generate id for it. + if (nodeInPersistenceCache == null) + { + idGenerator.generateAndSetId(entity, entityMetadata, pd); + } + } + + if (!validator.isValidEntityObject(entity)) + { + throw new IllegalArgumentException( + "Entity object is invalid, operation failed. Please check previous log message for details"); + } + + Object id = PropertyAccessorHelper.getId(entity, entityMetadata); + + String nodeId = ObjectGraphUtils.getNodeId(id, entity.getClass()); + Node node = graph.getNode(nodeId); + + // If this node is already there in graph (may happen for bidirectional + // relationship, do nothing and return null) + if (node != null) + { + if (node.isGraphCompleted()) + { + return node; + } + return null; + } + + // Construct this Node first, if one not already there in Persistence + // Cache + Node nodeInPersistenceCache = persistenceCache.getMainCache().getNodeFromCache(nodeId); + + // Make a deep copy of entity data + + if (nodeInPersistenceCache == null) + { + node = new Node(nodeId, entity, initialNodeState, persistenceCache, id); + } + else + { + node = nodeInPersistenceCache; + + // Determine whether this node is dirty based on comparison between + // Node data and entity data + // If dirty, set the entity data into node and mark it as dirty + if (!DeepEquals.deepEquals(node.getData(), entity)) + { + node.setData(entity); + node.setDirty(true); + } + else if (node.isProcessed()) + { + node.setDirty(false); + } + + // If node is NOT in managed state, its data needs to be + // replaced with the one provided in entity object + } + + // Put this node into object graph + graph.addNode(nodeId, node); + + // Iterate over relations and construct children nodes + for (Relation relation : entityMetadata.getRelations()) + { + + // Child Object set in this entity + Object childObject = PropertyAccessorHelper.getObject(entity, relation.getProperty()); + + if (childObject != null && !ProxyHelper.isProxy(childObject)) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(childObject.getClass()); + if (metadata != null && relation.isJoinedByPrimaryKey()) + { + PropertyAccessorHelper.setId(childObject, metadata, + PropertyAccessorHelper.getId(entity, entityMetadata)); + } + // This child object could be either an entity(1-1 or M-1) + // or a + // collection/ Map of entities(1-M or M-M) + if (Collection.class.isAssignableFrom(childObject.getClass())) + { + // For each entity in the collection, construct a child + // node and add to graph + Collection childrenObjects = (Collection) childObject; + + if (childrenObjects != null && !ProxyHelper.isProxyCollection(childrenObjects)) + + for (Object childObj : childrenObjects) + { + if (childObj != null) + { + addChildNodesToGraph(graph, node, relation, childObj, initialNodeState); + } + } + } + else if (Map.class.isAssignableFrom(childObject.getClass())) + { + Map childrenObjects = (Map) childObject; + if (childrenObjects != null && !ProxyHelper.isProxyCollection(childrenObjects)) + { + for (Map.Entry entry : (Set) childrenObjects.entrySet()) + { + addChildNodesToGraph(graph, node, relation, entry, initialNodeState); + } + } + } + else + { + // Construct child node and add to graph + addChildNodesToGraph(graph, node, relation, childObject, initialNodeState); + } + } + } + + // Means compelte graph is build. + node.setGraphCompleted(true); + return node; + } + + /** + * @param graph + * @param node + * @param relation + * @param childObject + */ + private void addChildNodesToGraph(ObjectGraph graph, Node node, Relation relation, Object childObject, + NodeState initialNodeState) + { + if (childObject instanceof KunderaProxy || childObject instanceof ProxyCollection) + { + return; + } + + else if (childObject instanceof Map.Entry) + { + Map.Entry entry = (Map.Entry) childObject; + Object relObject = entry.getKey(); + Object entityObject = entry.getValue(); + + Node childNode = getNode(entityObject, graph, initialNodeState); + + if (childNode != null) + { + if (!StringUtils.isEmpty(relation.getMappedBy()) + && relation.getProperty().getAnnotation(MapKeyJoinColumn.class) == null) + { + return; + } + + NodeLink nodeLink = new NodeLink(node.getNodeId(), childNode.getNodeId()); + nodeLink.setMultiplicity(relation.getType()); + + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(node.getDataClass()); + nodeLink.setLinkProperties(getLinkProperties(metadata, relation)); + + nodeLink.addLinkProperty(LinkProperty.LINK_VALUE, relObject); + + // Add Parent node to this child + childNode.addParentNode(nodeLink, node); + + // Add child node to this node + node.addChildNode(nodeLink, childNode); + } + } + else + { + // Construct child node for this child object via recursive call + Node childNode = getNode(childObject, graph, initialNodeState); + + if (childNode != null) + { + // Construct Node Link for this relationship + NodeLink nodeLink = new NodeLink(node.getNodeId(), childNode.getNodeId()); + nodeLink.setMultiplicity(relation.getType()); + + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(node.getDataClass()); + nodeLink.setLinkProperties(getLinkProperties(metadata, relation)); + + // Add Parent node to this child + childNode.addParentNode(nodeLink, node); + + // Add child node to this node + node.addChildNode(nodeLink, childNode); + } + } + } + + /** + * + * @param metadata + * Entity metadata of the parent node + * @param relation + * @return + */ + private Map getLinkProperties(EntityMetadata metadata, Relation relation) + { + Map linkProperties = new HashMap(); + + linkProperties.put(LinkProperty.LINK_NAME, MetadataUtils.getMappedName(metadata, relation)); + linkProperties.put(LinkProperty.IS_SHARED_BY_PRIMARY_KEY, relation.isJoinedByPrimaryKey()); + linkProperties.put(LinkProperty.IS_BIDIRECTIONAL, !relation.isUnary()); + linkProperties.put(LinkProperty.IS_RELATED_VIA_JOIN_TABLE, relation.isRelatedViaJoinTable()); + linkProperties.put(LinkProperty.PROPERTY, relation.getProperty()); + linkProperties.put(LinkProperty.CASCADE, relation.getCascades()); + + if (relation.isRelatedViaJoinTable()) + { + linkProperties.put(LinkProperty.JOIN_TABLE_METADATA, relation.getJoinTableMetadata()); + } + + // TODO: Add more link properties as required + return linkProperties; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphUtils.java b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphUtils.java new file mode 100644 index 000000000..45cb33398 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/graph/ObjectGraphUtils.java @@ -0,0 +1,46 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.graph; + +import com.impetus.kundera.Constants; + +/** + * Provides utility methods for object graph + * + * @author amresh.singh + */ +public class ObjectGraphUtils +{ + /* + * public static String getNodeId(Object pk, Object nodeData) { StringBuffer + * strBuffer = new StringBuffer(nodeData.getClass().getName()); + * strBuffer.append(Constants.NODE_ID_SEPARATOR); strBuffer.append(pk); + * return strBuffer.toString(); } + */ + + public static String getNodeId(Object pk, Class objectClass) + { + StringBuffer strBuffer = new StringBuffer(objectClass.getName()); + strBuffer.append(Constants.NODE_ID_SEPARATOR); + strBuffer.append(pk); + return strBuffer.toString(); + } + + public static Object getEntityId(String nodeId) + { + return nodeId.substring(nodeId.indexOf(Constants.NODE_ID_SEPARATOR) + 1, nodeId.length()); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/DocumentIndexer.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/DocumentIndexer.java new file mode 100644 index 000000000..2a7d40ee6 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/DocumentIndexer.java @@ -0,0 +1,398 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.io.CharArrayReader; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.LetterTokenizer; +import org.apache.lucene.analysis.Tokenizer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.util.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.PropertyIndex; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * The Class KunderaIndexer. + * + * @author animesh.kumar + */ +public abstract class DocumentIndexer implements com.impetus.kundera.index.lucene.Indexer +{ + + /** log for this class. */ + private static final Logger LOG = LoggerFactory.getLogger(DocumentIndexer.class); + + /** The INDEX_NAME. */ + protected static final String INDEX_NAME = "kundera-alpha";// is + + // persistent-unit-name + + /** The Constant UUID. */ + private static final long UUID = 6077004083174677888L; + + /** The Constant DELIMETER. */ + private static final String DELIMETER = "~"; + + /** The Constant ENTITY_ID_FIELD. */ + public static final String ENTITY_ID_FIELD = UUID + ".entity.id"; + + /** The Constant KUNDERA_ID_FIELD. */ + public static final String KUNDERA_ID_FIELD = UUID + ".kundera.id"; + + /** The Constant ENTITY_INDEXNAME_FIELD. */ + public static final String ENTITY_INDEXNAME_FIELD = UUID + ".entity.indexname"; + + /** The Constant ENTITY_CLASS_FIELD. */ + public static final String ENTITY_CLASS_FIELD = /* UUID + */"entity.class"; + + /** The Constant DEFAULT_SEARCHABLE_FIELD. */ + protected static final String DEFAULT_SEARCHABLE_FIELD = UUID + ".default_property"; + + /** The Constant SUPERCOLUMN_INDEX. */ + protected static final String SUPERCOLUMN_INDEX = UUID + ".entity.super.indexname"; + + /** The Constant PARENT_ID_FIELD. */ + public static final String PARENT_ID_FIELD = UUID + ".parent.id"; + + /** The Constant PARENT_ID_CLASS. */ + public static final String PARENT_ID_CLASS = UUID + ".parent.class"; + + /** The doc number. */ + protected static int docNumber = 1; + + /** The analyzer. */ + protected Analyzer analyzer; + + /** The tokenizer. */ + protected Tokenizer tokenizer; + + /** + * Instantiates a new lucandra indexer. + * + * @param analyzer + * the analyzer + */ + public DocumentIndexer(Analyzer analyzer) + { + final String empty = ""; + this.analyzer = analyzer; + tokenizer = new LetterTokenizer(Version.LUCENE_34, new CharArrayReader(empty.toCharArray())); + } + + /** + * Prepare document. + * + * @param metadata + * the metadata + * @param object + * the object + * @param embeddedColumnName + * the super column name + * @param parentId + * the parent id + * @param clazz + * the clazz + * @return the document + */ + protected Document prepareDocumentForSuperColumn(EntityMetadata metadata, Object object, String embeddedColumnName, + String parentId, Class clazz) + { + Document currentDoc; + currentDoc = new Document(); + + // Add entity class and row key info to document + addEntityClassToDocument(metadata, object, currentDoc); + + // Add super column name to document + addSuperColumnNameToDocument(embeddedColumnName, currentDoc); + + indexParentKey(parentId, currentDoc, clazz); + return currentDoc; + } + + /** + * Index parent key. + * + * @param parentId + * the parent id + * @param currentDoc + * the current doc + * @param clazz + * the clazz + */ + protected void indexParentKey(String parentId, Document currentDoc, Class clazz) + { + if (parentId != null) + { + Field luceneField = new Field(PARENT_ID_FIELD, parentId, Field.Store.YES, Field.Index.ANALYZED_NO_NORMS); + currentDoc.add(luceneField); + Field fieldClass = new Field(PARENT_ID_CLASS, clazz.getCanonicalName().toLowerCase(), Field.Store.YES, + Field.Index.ANALYZED); + currentDoc.add(fieldClass); + } + } + + /** + * Index super column. + * + * @param metadata + * the metadata + * @param object + * the object + * @param currentDoc + * the current doc + * @param embeddedObject + * the embedded object + * @param superColumn + * the super column + */ + protected void indexSuperColumn(EntityMetadata metadata, Object object, Document currentDoc, Object embeddedObject, + EmbeddableType superColumn) + { + + // Add all super column fields into document + Set attributes = superColumn.getAttributes(); + Iterator iter = attributes.iterator(); + while (iter.hasNext()) + { + Attribute attr = iter.next(); + java.lang.reflect.Field field = (java.lang.reflect.Field) attr.getJavaMember(); + String colName = field.getName(); + String indexName = metadata.getIndexName(); + addFieldToDocument(embeddedObject, currentDoc, field, colName, indexName); + + } + // for (Column col : superColumn.getColumns()) + // { + // java.lang.reflect.Field field = col.getField(); + // String colName = field.getName(); + // String indexName = metadata.getIndexName(); + // addFieldToDocument(embeddedObject, currentDoc, field, colName, + // indexName); + // } + // Add all entity fields to document + addEntityFieldsToDocument(metadata, object, currentDoc); + + // Store document into Index + indexDocument(metadata, currentDoc); + + } + + /** + * Index super column name. + * + * @param superColumnName + * the super column name + * @param currentDoc + * the current doc + */ + private void addSuperColumnNameToDocument(String superColumnName, Document currentDoc) + { + Field luceneField = new Field(SUPERCOLUMN_INDEX, superColumnName, Store.YES, Field.Index.NO); + currentDoc.add(luceneField); + } + + /** + * Adds the index properties. + * + * @param metadata + * the metadata + * @param object + * the object + * @param document + * the document + */ + protected void addEntityFieldsToDocument(EntityMetadata metadata, Object object, Document document) + { + String indexName = metadata.getIndexName(); + + // for (PropertyIndex index : metadata.getIndexProperties()) + // { + // java.lang.reflect.Field property = index.getProperty(); + // String propertyName = index.getName(); + // addFieldToDocument(object, document, property, propertyName, + // indexName); + // } + + Map indexProperties = metadata.getIndexProperties(); + for (String columnName : indexProperties.keySet()) + { + PropertyIndex index = indexProperties.get(columnName); + java.lang.reflect.Field property = index.getProperty(); + String propertyName = index.getName(); + addFieldToDocument(object, document, property, propertyName, indexName); + } + } + + /** + * Prepare index document. + * + * @param metadata + * the metadata + * @param object + * the object + * @param document + * the document + */ + protected void addEntityClassToDocument(EntityMetadata metadata, Object object, Document document) + { + try + { + + Field luceneField; + Object id; + id = PropertyAccessorHelper.getId(object, metadata); + luceneField = new Field(ENTITY_ID_FIELD, id.toString(), Field.Store.YES, Field.Index.ANALYZED); + + // luceneField.set + // adding class + // namespace + // /*Field.Store.YES, Field.Index.ANALYZED_NO_NORMS*/); + document.add(luceneField); + + // index namespace for unique deletion + luceneField = new Field(KUNDERA_ID_FIELD, getKunderaId(metadata, id), Field.Store.YES, Field.Index.ANALYZED); // adding + // class + // namespace + // Field.Store.YES/*, Field.Index.ANALYZED_NO_NORMS*/); + document.add(luceneField); + + // index entity class + luceneField = new Field(ENTITY_CLASS_FIELD, metadata.getEntityClazz().getCanonicalName().toLowerCase(), + Field.Store.YES, Field.Index.ANALYZED); + document.add(luceneField); + // + luceneField = new Field("timestamp", System.currentTimeMillis() + "", Field.Store.YES, Field.Index.NO); + document.add(luceneField); + + // index index name + luceneField = new Field(ENTITY_INDEXNAME_FIELD, metadata.getIndexName(), Field.Store.NO, + Field.Index.ANALYZED_NO_NORMS); + document.add(luceneField); + + luceneField = new Field(getCannonicalPropertyName(metadata.getEntityClazz().getSimpleName(), + ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName()), id.toString(), + Field.Store.YES, Field.Index.ANALYZED_NO_NORMS); + document.add(luceneField); + } + catch (PropertyAccessException e) + { + throw new IllegalArgumentException("Id could not be read from object " + object); + } + } + + /** + * Index field. + * + * @param object + * the object + * @param document + * the document + * @param field + * the field + * @param colName + * the col name + * @param indexName + * the index name + */ + private void addFieldToDocument(Object object, Document document, java.lang.reflect.Field field, String colName, + String indexName) + { + try + { + Object obj = PropertyAccessorHelper.getObject(object, field); + // String value = (obj == null) ? null : obj.toString(); + if (obj != null) + { + Field luceneField = new Field(getCannonicalPropertyName(indexName, colName), obj.toString(), + Field.Store.YES, Field.Index.ANALYZED_NO_NORMS); + + document.add(luceneField); + } + else + { + LOG.warn("value is null for field" + field.getName()); + } + } + catch (PropertyAccessException e) + { + LOG.error("Error in accessing field, Caused by:" + e.getMessage()); + throw new LuceneIndexingException("Error in accessing field:" + field.getName(), e); + } + } + + @Override + public Map search(Class parentClass, Class childClass, Object entityId, int start, int count) + { + return null; + } + + /** + * Gets the kundera id. + * + * @param metadata + * the metadata + * @param id + * the id + * + * @return the kundera id + */ + protected String getKunderaId(EntityMetadata metadata, Object id) + { + return metadata.getEntityClazz().getCanonicalName() + DELIMETER + id; + } + + /** + * Gets the cannonical property name. + * + * @param indexName + * the index name + * @param propertyName + * the property name + * + * @return the cannonical property name + */ + protected String getCannonicalPropertyName(String indexName, String propertyName) + { + return indexName + "." + propertyName; + } + + /** + * Index document. + * + * @param metadata + * the metadata + * @param currentDoc + * the current doc + */ + protected abstract void indexDocument(EntityMetadata metadata, Document currentDoc); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/Index.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/Index.java new file mode 100644 index 000000000..78b74efef --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/Index.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation interface for column + * + * @author Kuldeep Mishra + * + */ +@Target({ ElementType.TYPE, ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Index +{ + + /** + * Column to index. + * + * @return the string + */ + public abstract String name(); + + /** + * Type of index. + * + * @return the string + */ + public abstract String type() default ""; + + /** + * Max value of index column. + * + * @return + */ + public abstract int max() default Integer.MAX_VALUE; + + /** + * Min value of index column. + * + * @return + */ + public abstract int min() default Integer.MIN_VALUE; + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexCollection.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexCollection.java new file mode 100644 index 000000000..8ad652792 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexCollection.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation interface for collection of {@link Index} + * + * @author Kuldeep Mishra + * + */ +@Target({ ElementType.TYPE, ElementType.FIELD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface IndexCollection +{ + /** + * Array of index columns to index. + * + * @return the string[] + */ + public abstract Index[] columns(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexManager.java new file mode 100644 index 000000000..be863b675 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexManager.java @@ -0,0 +1,394 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PropertyIndex; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Manager responsible to co-ordinate with an Indexer. It is bound with + * EntityManager. + * + * @author animesh.kumar + */ +public class IndexManager +{ + + /** The indexer. */ + private Indexer indexer; + + /** + * The Constructor. + * + * @param indexer + * the indexer + */ + @SuppressWarnings("deprecation") + public IndexManager(Indexer indexer) + { + this.indexer = indexer; + } + + /** + * @return the indexer + */ + public Indexer getIndexer() + { + return indexer; + } + + /** + * Removes an object from Index. + * + * @param metadata + * the metadata + * @param entity + * the entity + * @param key + * the key + */ + public final void remove(EntityMetadata metadata, Object entity, String key) + { + if (indexer != null) + { + + if (indexer.getClass().isAssignableFrom(LuceneIndexer.class)) + { + ((com.impetus.kundera.index.lucene.Indexer) indexer).unindex(metadata, key); + } + else + { + indexer.unIndex(metadata.getEntityClazz(), entity); + } + } + } + + /** + * Updates the index for an object. + * + * @param metadata + * the metadata + * @param entity + * the entity + */ + public final void update(EntityMetadata metadata, Object entity, Object parentId, Class clazz) + { + + try + { + if (indexer != null) + { + if (indexer.getClass().isAssignableFrom(LuceneIndexer.class)) + { + Object id = PropertyAccessorHelper.getId(entity, metadata); + + boolean documentExists = ((com.impetus.kundera.index.lucene.Indexer) indexer) + .entityExistsInIndex(entity.getClass()); + if (documentExists) + { + ((com.impetus.kundera.index.lucene.Indexer) indexer).unindex(metadata, id); + ((com.impetus.kundera.index.lucene.Indexer) indexer).flush(); + } + ((com.impetus.kundera.index.lucene.Indexer) indexer).index(metadata, entity, + parentId != null ? parentId.toString() : null, clazz); + } + else + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetamodel(metadata.getPersistenceUnit()); + + Map indexProperties = metadata.getIndexProperties(); + Map indexCollection = new HashMap(); + Object id = PropertyAccessorHelper.getId(entity, metadata); + for (String columnName : indexProperties.keySet()) + { + PropertyIndex index = indexProperties.get(columnName); + java.lang.reflect.Field property = index.getProperty(); + // String propertyName = index.getName(); + Object obj = PropertyAccessorHelper.getObject(entity, property); + indexCollection.put(columnName, obj); + + } + + indexCollection.put(((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName(), id); + + EntityMetadata parentMetadata = KunderaMetadataManager.getEntityMetadata(clazz); + if (parentId != null) + indexCollection.put(((AbstractAttribute) parentMetadata.getIdAttribute()).getJPAColumnName(), + parentId); + + onEmbeddable(entity, metadata.getEntityClazz(), metaModel, indexCollection); + indexer.index(metadata.getEntityClazz(), indexCollection); + } + } + } + catch (PropertyAccessException e) + { + throw new IndexingException("Can't access ID from entity class " + metadata.getEntityClazz(), e); + } + } + + /** + * @param entity + * @param clazz + * @param metaModel + * @param indexCollection + */ + private void onEmbeddable(Object entity, Class clazz, MetamodelImpl metaModel, + Map indexCollection) + { + Map embeddables = metaModel.getEmbeddables(clazz); + EntityType entityType = metaModel.entity(clazz); + + for (String embeddedFieldName : embeddables.keySet()) + { + EmbeddableType embeddedColumn = embeddables.get(embeddedFieldName); + + // Index embeddable only when specified by user + Field embeddedField = (Field) entityType.getAttribute(embeddedFieldName).getJavaMember(); + if (!MetadataUtils.isEmbeddedAtributeIndexable(embeddedField)) + { + continue; + } + + Object embeddedObject = PropertyAccessorHelper.getObject(entity, + (Field) entityType.getAttribute(embeddedFieldName).getJavaMember()); + if (embeddedObject != null && !(embeddedObject instanceof Collection)) + { + for (Object column : embeddedColumn.getAttributes()) + { + Attribute columnAttribute = (Attribute) column; + String columnName = columnAttribute.getName(); + Class columnClass = ((AbstractAttribute) columnAttribute).getBindableJavaType(); + if (MetadataUtils.isColumnInEmbeddableIndexable(embeddedField, columnName)) + { + indexCollection.put( + embeddedField.getName() + "." + columnName, + PropertyAccessorHelper.getObject(embeddedObject, + (Field) columnAttribute.getJavaMember())); + } + } + } + + } + } + + /** + * Indexes an object. + * + * @param metadata + * the metadata + * @param entity + * the entity + */ + public final void write(EntityMetadata metadata, Object entity) + { + if (indexer != null) + { + ((com.impetus.kundera.index.lucene.Indexer) indexer).index(metadata, entity); + } + } + + /** + * Indexes an object. + * + * @param metadata + * the metadata + * @param entity + * the entity + * @param parentId + * parent Id. + * @param clazz + * class name + */ + public final void write(EntityMetadata metadata, Object entity, String parentId, Class clazz) + { + if (indexer != null) + { + + ((com.impetus.kundera.index.lucene.Indexer) indexer).index(metadata, entity, parentId, clazz); + } + } + + /** + * Searches on the index. Note: Query must be in Indexer's understandable + * format + * + * @param query + * the query + * @return the list + */ + @Deprecated + // TODO: All lucene specific code (methods that accept lucene query as + // parameter) from this class should go away + // and should be moved to LuceneIndexer instead + public final Map search(String query) + { + + return search(query, Constants.INVALID, Constants.INVALID, false); + } + + public final Map search(Class parentClass, Class childClass, Object entityId) + { + if (indexer == null) + return null; + + if (indexer != null && indexer.getClass().isAssignableFrom(LuceneIndexer.class)) + { + + // Search into Lucene index using lucene query, where entity class + // is child class, parent class is + // entity's class and parent Id is entity ID! that's it! + String query = LuceneQueryUtils.getQuery(DocumentIndexer.PARENT_ID_CLASS, parentClass.getCanonicalName() + .toLowerCase(), DocumentIndexer.PARENT_ID_FIELD, entityId, childClass.getCanonicalName() + .toLowerCase()); + return ((com.impetus.kundera.index.lucene.Indexer) indexer).search(query, Constants.INVALID, + Constants.INVALID, false); + } + else + { + // If an alternate indexer implementation class is provided by user, + // search into that + return indexer.search(parentClass, childClass, entityId, Constants.INVALID, Constants.INVALID); + } + + } + + /** + * Searches on the index. Note: Query must be in Indexer's understandable + * format + * + * @param query + * the query + * @return the list + */ + public final Map fetchRelation(String query) + { + // TODO: need to return list. + return search(query, Constants.INVALID, Constants.INVALID, true); + } + + /** + * Search. + * + * @param query + * the query + * @param count + * the count + * @return the list + */ + public final Map search(String query, int count) + { + return search(query, Constants.INVALID, count, false); + } + + /** + * Search. + * + * @param query + * the query + * @param start + * the start + * @param count + * the count + * @return the list + */ + public final Map search(String query, int start, int count) + { + if (indexer != null) + { + if (indexer != null && indexer.getClass().isAssignableFrom(LuceneIndexer.class)) + { + return indexer != null ? ((com.impetus.kundera.index.lucene.Indexer) indexer).search(query, start, + count, false) : null; + } + else + { + return indexer.search(query, start, count); + } + } + return new HashMap(); + } + + /** + * Search. + * + * @param query + * the query + * @param start + * the start + * @param count + * the count + * @param fetchRelation + * the fetch relation + * @return the list + */ + public final Map search(String query, int start, int count, boolean fetchRelation) + { + if (indexer != null) + { + if (indexer.getClass().isAssignableFrom(LuceneIndexer.class)) + { + return indexer != null ? ((com.impetus.kundera.index.lucene.Indexer) indexer).search(query, start, + count, fetchRelation) : null; + } + else + { + return indexer.search(query, start, count); + } + } + return new HashMap(); + } + + /** + * Flushes out the indexes, keeping RAM directory open. + */ + public void flush() throws IndexingException + { + if (indexer != null) + { + ((com.impetus.kundera.index.lucene.Indexer) indexer).flush(); + } + } + + /** + * Closes the transaction along with RAM directory. + */ + public void close() throws IndexingException + { + if (indexer != null) + { + indexer.close(); + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/Indexer.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/Indexer.java new file mode 100644 index 000000000..6799d99ae --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/Indexer.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.util.Map; + +/** + * Indexer interface. Any custom implementation for this interface can be + * plugged-in by configuring kundera.indexer.class property in persistence.xml. + * Once this is enabled in persistence provider, Kundera will automatically + * delegate index related requests to configure indexer interface implementation + * but will keep functioning for any database specific requests. For example, + * developer may rely upon custom index implementation for inverted indexes(e.g. @Id + * attributes) but entity data population will be handled by Kundera + * + * @author vivek.mishra + * + */ +public interface Indexer +{ + + /** + * Index a document for given entity class and collection of values. + * + * @param entityClazz + * entity class + * + * @param values + * map of values containing field name as key and it's value. + */ + void index(final Class entityClazz, final Map values); + + /** + * Executes lucene query and returns inverted indices as output. TODO: + * Indexer interface shouldn't make any assumption about its implementation, + * this method signature accepts lucene query, and hence should go away + * + * @param queryString + * lucene query. + * @param start + * start counter + * @param end + * end counter + * @return collection containing stored index value. + */ + @Deprecated + Map search(final String queryString, int start, int count); + + /** + * Searches into a secondary index + * + * @return + */ + Map search(Class parentClass, Class childClass, Object entityId, int start, int count); + + /** + * Deletes index for given entity class. + * + * @param entityClazz + * entity class + * + * @param entity + * Entity object + */ + void unIndex(final Class entityClazz, final Object entity); + + void close(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexingException.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexingException.java new file mode 100644 index 000000000..fa592bf25 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/IndexingException.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import com.impetus.kundera.KunderaException; + +/** + * Captures any indexing related exceptions. + * + * @author animesh.kumar + */ +public class IndexingException extends KunderaException +{ + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 7917821486831927353L; + + /** + * + */ + public IndexingException() + { + super(); + + } + + /** + * @param arg0 + * @param arg1 + */ + public IndexingException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public IndexingException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public IndexingException(Throwable arg0) + { + super(arg0); + + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexer.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexer.java new file mode 100644 index 000000000..50a42e7ab --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexer.java @@ -0,0 +1,659 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.index.LogDocMergePolicy; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.Directory; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.LockObtainFailedException; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.cache.ElementCollectionCacheManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Provides indexing functionality using lucene library. + * + * @author amresh.singh + */ +public class LuceneIndexer extends DocumentIndexer +{ + + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(LuceneIndexer.class); + + /** The w. */ + private static IndexWriter w; + + /** The reader. */ + private static IndexReader reader; + + /** The index. */ + private static Directory index; + + /** The is initialized. */ + private static boolean isInitialized; + + /** The indexer. */ + private static LuceneIndexer indexer; + + /** The ready for commit. */ + private static boolean readyForCommit; + + /** The lucene dir path. */ + private static String luceneDirPath; + + /** + * Instantiates a new lucene indexer. + * + * @param analyzer + * the analyzer + * @param lucDirPath + * the luc dir path + */ + private LuceneIndexer(Analyzer analyzer, String lucDirPath) + { + super(analyzer); + try + { + luceneDirPath = lucDirPath; + File file = new File(luceneDirPath); + if (file.exists()) + { + Directory sourceDir = FSDirectory.open(getIndexDirectory()); + index = new RAMDirectory(sourceDir); + } + else + { + index = new RAMDirectory(); + } + /* + * FSDirectory.open(getIndexDirectory( )) + */ + // isInitialized + /* writer */ + w = new IndexWriter(index, new IndexWriterConfig(Version.LUCENE_34, analyzer)); + /* reader = */ + w.setMergePolicy(new LogDocMergePolicy()); + // w.setMergeFactor(1); + w.setMergeFactor(1000); + w.getConfig().setRAMBufferSizeMB(32); + } + catch (CorruptIndexException e) + { + throw new LuceneIndexingException(e); + } + catch (LockObtainFailedException e) + { + throw new LuceneIndexingException(e); + } + catch (IOException e) + { + throw new LuceneIndexingException(e); + } + } + + /** + * Gets the single instance of LuceneIndexer. + * + * @param analyzer + * the analyzer + * @param lucDirPath + * the luc dir path + * @return single instance of LuceneIndexer + */ + public static synchronized LuceneIndexer getInstance(Analyzer analyzer, String lucDirPath) + { + // super(analyzer); + if (indexer == null && lucDirPath != null) + { + indexer = new LuceneIndexer(analyzer, lucDirPath); + + } + return indexer; + } + + /** + * Added for HBase support. + * + * @return default index writer + */ + private IndexWriter getIndexWriter() + { + return w; + } + + /** + * Returns default index reader. + * + * @return index reader. + */ + private IndexReader getIndexReader() + { + flushInternal(); + + if (reader == null) + { + try + { + if (!isInitialized) + { + Directory sourceDir = FSDirectory.open(getIndexDirectory()); + sourceDir.copy(sourceDir, index, true); + isInitialized = true; + } + reader = IndexReader.open(index, true); + } + catch (CorruptIndexException e) + { + throw new LuceneIndexingException(e); + } + catch (IOException e) + { + throw new LuceneIndexingException(e); + } + } + return reader; + } + + /** + * Creates a Lucene index directory if it does not exist. + * + * @return the index directory + */ + private File getIndexDirectory() + { + File file = new File(luceneDirPath); + + if (!file.isDirectory()) + { + file.mkdir(); + } + return file; + } + + @Override + public final void index(EntityMetadata metadata, Object object) + { + indexDocument(metadata, object, null, null); + onCommit(); + } + + @Override + public final void unindex(EntityMetadata metadata, Object id) throws LuceneIndexingException + { + if (log.isDebugEnabled()) + log.debug("Unindexing @Entity[" + metadata.getEntityClazz().getName() + "] for key:" + id); + try + { + String luceneQuery = "+" + + ENTITY_CLASS_FIELD + + ":" + + metadata.getEntityClazz().getCanonicalName().toLowerCase() + + " AND +" + + getCannonicalPropertyName(metadata.getEntityClazz().getSimpleName(), + ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName()) + ":" + id.toString(); + + /* String indexName, Query query, boolean autoCommit */ + // w.deleteDocuments(new Term(KUNDERA_ID_FIELD, + // getKunderaId(metadata, id))); + + QueryParser qp = new QueryParser(Version.LUCENE_34, DEFAULT_SEARCHABLE_FIELD, new StandardAnalyzer( + Version.LUCENE_34)); + qp.setLowercaseExpandedTerms(false); + qp.setAllowLeadingWildcard(true); + // qp.set + Query q = qp.parse(luceneQuery); + + w.deleteDocuments(q); + w.commit(); + w.close(); + w = new IndexWriter(index, new IndexWriterConfig(Version.LUCENE_34, analyzer)); + /* reader = */ + w.setMergePolicy(new LogDocMergePolicy()); + // w.setMergeFactor(1); + w.setMergeFactor(1000); + w.getConfig().setRAMBufferSizeMB(32); + // flushInternal(); + } + catch (CorruptIndexException e) + { + throw new LuceneIndexingException(e); + } + catch (IOException e) + { + throw new LuceneIndexingException(e); + } + catch (ParseException e) + { + throw new LuceneIndexingException(e); + } + } + + @SuppressWarnings("deprecation") + @Override + public final Map search(String luceneQuery, int start, int count, boolean fetchRelation) + { + + reader = getIndexReader(); + if (Constants.INVALID == count) + { + count = 100; + } + + if (log.isDebugEnabled()) + log.debug("Searching index with query[" + luceneQuery + "], start:" + start + ", count:" + count); + + // Set entityIds = new HashSet(); + Map indexCol = new HashMap(); + + if (reader == null) + { + throw new LuceneIndexingException("Index reader is not initialized!"); + } + + IndexSearcher searcher = new IndexSearcher(reader); + QueryParser qp = new QueryParser(Version.LUCENE_34, DEFAULT_SEARCHABLE_FIELD, new StandardAnalyzer( + Version.LUCENE_34)); + + try + { + qp.setLowercaseExpandedTerms(false); + qp.setAllowLeadingWildcard(true); + // qp.set + Query q = qp.parse(luceneQuery); + TopDocs docs = searcher.search(q, count); + + int nullCount = 0; + // Assuming Supercol will be null in case if alias only. + // This is a quick fix + for (ScoreDoc sc : docs.scoreDocs) + { + Document doc = searcher.doc(sc.doc); + String entityId = doc.get(fetchRelation ? PARENT_ID_FIELD : ENTITY_ID_FIELD); + String superCol = doc.get(SUPERCOLUMN_INDEX); + + if (superCol == null) + { + superCol = "SuperCol" + nullCount++; + } + // In case of super column and association. + indexCol.put(superCol + "|" + entityId, entityId); + } + } + catch (ParseException e) + { + throw new LuceneIndexingException("Error while parsing Lucene Query " + luceneQuery, e); + } + catch (IOException e) + { + throw new LuceneIndexingException(e); + } + + reader = null; + return indexCol; + } + + /** + * Indexes document in file system using lucene. + * + * @param metadata + * the metadata + * @param document + * the document + */ + public void indexDocument(EntityMetadata metadata, Document document) + { + if (log.isDebugEnabled()) + log.debug("Indexing document: " + document + " for in file system using Lucene"); + + IndexWriter w = getIndexWriter(); + try + { + // w.setR + w.addDocument(document); + // w.optimize(); + // w.commit(); + // w.close(); + } + catch (CorruptIndexException e) + { + log.error("Error while indexing document " + document + " into Lucene, Caused by: ", e); + throw new LuceneIndexingException("Error while indexing document " + document + " into Lucene.", e); + } + catch (IOException e) + { + log.error("Error while indexing document " + document + " into Lucene, Caused by: ", e); + throw new LuceneIndexingException("Error while indexing document " + document + " into Lucene.", e); + } + } + + /** + * Flush internal. + */ + private void flushInternal() + { + try + { + if (w != null && readyForCommit) + { + w.optimize(); + w.commit(); + index.copy(index, FSDirectory.open(getIndexDirectory()), false); + readyForCommit = false; + reader = null; + isInitialized = false; + } + } + + catch (CorruptIndexException e) + { + log.error("Error while Flushing Lucene Indexes, Caused by: ", e); + throw new LuceneIndexingException("Error while Flushing Lucene Indexes", e); + } + catch (IOException e) + { + log.error("Error while Flushing Lucene Indexes" + e.getMessage()); + throw new LuceneIndexingException("Error while Flushing Lucene Indexes", e); + } + } + + /** + * Close of transaction. + */ + public void close() + { + try + { + if (w != null && readyForCommit) + { + w.commit(); + index.copy(index, FSDirectory.open(getIndexDirectory()), false); + } + } + + catch (CorruptIndexException e) + { + log.error("Error while closing lucene indexes, Caused by: ", e); + throw new LuceneIndexingException("Error while closing lucene indexes.", e); + } + catch (IOException e) + { + log.error("Error while closing lucene indexes, Caused by: ", e); + throw new LuceneIndexingException("Error while closing lucene indexes.", e); + } + } + + @Override + public void flush() + { + /* + * if (w != null) { + * + * try { w.commit(); // w.close(); // index.copy(index, + * FSDirectory.open(getIndexDirectory()), false); } catch + * (CorruptIndexException e) { } catch (IOException e) { } } + */ + } + + @Override + public void index(EntityMetadata metadata, Object object, String parentId, Class clazz) + { + + indexDocument(metadata, object, parentId, clazz); + onCommit(); + } + + @Override + public boolean entityExistsInIndex(Class entityClass) + { + String luceneQuery = "+" + ENTITY_CLASS_FIELD + ":" + entityClass.getCanonicalName().toLowerCase(); + Map results; + try + { + results = search(luceneQuery, 0, 10, false); + } + catch (LuceneIndexingException e) + { + return false; + } + if (results == null || results.isEmpty()) + { + return false; + } + else + { + return true; + } + } + + /** + * Index document. + * + * @param metadata + * the metadata + * @param object + * the object + * @param parentId + * the parent id + * @param clazz + * the clazz + * @return the document + */ + private Document indexDocument(EntityMetadata metadata, Object object, String parentId, Class clazz) + { + if (!metadata.isIndexable()) + { + return null; + } + + if (log.isDebugEnabled()) + log.debug("Indexing @Entity[" + metadata.getEntityClazz().getName() + "] " + object); + + Document currentDoc = null; + Object embeddedObject = null; + Object rowKey = null; + try + { + rowKey = PropertyAccessorHelper.getId(object, metadata); + } + catch (PropertyAccessException e1) + { + throw new LuceneIndexingException("Can't access Primary key property from " + metadata.getEntityClazz(), e1); + } + + // In case defined entity is Super column family. + // we need to create seperate lucene document for indexing. + + if (metadata.getType().equals(EntityMetadata.Type.SUPER_COLUMN_FAMILY)) + { + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + + Map embeddables = metaModel.getEmbeddables(metadata.getEntityClazz()); + + // Map embeddedColumnMap = + // metadata.getEmbeddedColumnsMap(); + + Iterator iter = embeddables.keySet().iterator(); + + while (iter.hasNext()) + { + // for(EmbeddableType embeddableAttribute : + // embeddables.values()) + // { + String attributeName = iter.next(); + EmbeddableType embeddableAttribute = embeddables.get(attributeName); + EntityType entityType = metaModel.entity(metadata.getEntityClazz()); + embeddedObject = PropertyAccessorHelper.getObject(object, (Field) entityType + .getAttribute(attributeName).getJavaMember()); + + if (embeddedObject == null) + { + continue; + } + if (embeddedObject instanceof Collection) + { + ElementCollectionCacheManager ecCacheHandler = ElementCollectionCacheManager.getInstance(); + // Check whether it's first time insert or updation + if (ecCacheHandler.isCacheEmpty()) + { // First time + // insert + int count = 0; + for (Object obj : (Collection) embeddedObject) + { + String elementCollectionObjectName = attributeName + + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + count; + + currentDoc = prepareDocumentForSuperColumn(metadata, object, elementCollectionObjectName, + parentId, clazz); + indexSuperColumn(metadata, object, currentDoc, obj, embeddableAttribute); + count++; + } + } + else + { + // Updation, Check whether this object is already in + // cache, which means we already have an embedded + // column + // Otherwise we need to generate a fresh embedded + // column name + int lastEmbeddedObjectCount = ecCacheHandler.getLastElementCollectionObjectCount(rowKey); + for (Object obj : (Collection) embeddedObject) + { + String elementCollectionObjectName = ecCacheHandler.getElementCollectionObjectName(rowKey, + obj); + if (elementCollectionObjectName == null) + { // Fresh + // row + elementCollectionObjectName = attributeName + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + + (++lastEmbeddedObjectCount); + } + + currentDoc = prepareDocumentForSuperColumn(metadata, object, elementCollectionObjectName, + parentId, clazz); + indexSuperColumn(metadata, object, currentDoc, obj, embeddableAttribute); + } + } + + } + else + { + currentDoc = prepareDocumentForSuperColumn(metadata, object, attributeName, parentId, clazz); + indexSuperColumn(metadata, object, currentDoc, + metaModel.isEmbeddable(embeddedObject.getClass()) ? embeddedObject : object, + embeddableAttribute); + } + } + } + else + { + currentDoc = new Document(); + + // Add entity class, PK info into document + + addEntityClassToDocument(metadata, object, currentDoc); + + // Add all entity fields(columns) into document + addEntityFieldsToDocument(metadata, object, currentDoc); + + indexParentKey(parentId, currentDoc, clazz); + // Store document into index + indexDocument(metadata, currentDoc); + } + + return currentDoc; + } + + /** + * On commit. + */ + private void onCommit() + { + // TODO: Sadly this required to keep lucene happy, in case of indexing + // and searching with same entityManager. + // Other alternative would be to issue flush on each search + // try + // { + // w.commit(); + isInitialized = true; + readyForCommit = true; + // } + // catch (CorruptIndexException e) + // { + // throw new IndexingException(e.getMessage()); + // } + // catch (IOException e) + // { + // throw new IndexingException(e.getMessage()); + // } + } + + @Override + public void index(Class entityClazz, Map values) + { + throw new UnsupportedOperationException("Method not supported"); + } + + @Override + public void unIndex(Class entityClazz, Object entity) + { + throw new UnsupportedOperationException("Method not supported"); + } + + @Override + public Map search(String luceneQuery, int start, int end) + { + throw new UnsupportedOperationException("Method not supported"); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexingException.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexingException.java new file mode 100644 index 000000000..98ed3bbff --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneIndexingException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index; + +/** + * @author amresh.singh + * + */ +public class LuceneIndexingException extends IndexingException +{ + /** + * + */ + private static final long serialVersionUID = -9021996457355536038L; + + /** + * + */ + public LuceneIndexingException() + { + } + + /** + * @param arg0 + * @param arg1 + */ + public LuceneIndexingException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public LuceneIndexingException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public LuceneIndexingException(Throwable arg0) + { + super(arg0); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneQueryUtils.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneQueryUtils.java new file mode 100644 index 000000000..82d6788f4 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/LuceneQueryUtils.java @@ -0,0 +1,90 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.index; + +/** + * Provides utility methods for Lucene Query related functionality + * + * @author amresh.singh + */ +public class LuceneQueryUtils +{ + /** + * Returns lucene based query. + * + * @param clazzFieldName + * lucene field name for class + * @param clazzName + * class name + * @param idFieldName + * lucene id field name + * @param idFieldValue + * lucene id field value + * @return query lucene query. + */ + public static String getQuery(String clazzFieldName, String clazzName, String idFieldName, String idFieldValue) + { + StringBuffer sb = new StringBuffer("+"); + sb.append(clazzFieldName); + sb.append(":"); + sb.append(clazzName); + sb.append(" AND "); + sb.append("+"); + sb.append(idFieldName); + sb.append(":"); + sb.append(idFieldValue); + return sb.toString(); + } + + /** + * Returns lucene based query. + * + * @param clazzFieldName + * lucene field name for class + * @param clazzName + * class name + * @param idFieldName + * lucene id field name + * @param idFieldValue + * lucene id field value + * @param entityClazz + * the entity clazz + * @return query lucene query. + */ + public static String getQuery(String clazzFieldName, String clazzName, String idFieldName, Object idFieldValue, + String entityClazz) + { + StringBuffer sb = new StringBuffer("+"); + sb.append(clazzFieldName); + sb.append(":"); + sb.append(clazzName); + sb.append(" AND "); + sb.append("+"); + sb.append(idFieldName); + sb.append(":"); + sb.append(idFieldValue); + if (entityClazz != null) + { + sb.append(" AND "); + sb.append("+"); + sb.append(DocumentIndexer.ENTITY_CLASS_FIELD); + sb.append(":"); + sb.append(entityClazz); + } + return sb.toString(); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/index/lucene/Indexer.java b/src/kundera-core/src/main/java/com/impetus/kundera/index/lucene/Indexer.java new file mode 100644 index 000000000..be7533237 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/index/lucene/Indexer.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.index.lucene; + +import java.util.Map; + +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Interface to define the behavior of an Indexer. + * + * @author animesh.kumar + */ +public interface Indexer extends com.impetus.kundera.index.Indexer +{ + + /** + * Unindexed an entity with key:id. + * + * @param metadata + * the metadata + * @param id + * the id + */ + + void unindex(EntityMetadata metadata, Object id); + + /** + * Indexes and object. + * + * @param metadata + * the metadata + * @param object + * the object + */ + void index(EntityMetadata metadata, Object object); + + /** + * Indexes and object. + * + * @param metadata + * the meta data. + * @param object + * the object. + * @param parentId + * parent Id. + * @param clazz + * parent class. + */ + void index(EntityMetadata metadata, Object object, String parentId, Class clazz); + + /** + * Searches for an object. Note that the "query" must be in Indexer + * specified form. + * + * @param luceneQuery + * the lucene query + * @param start + * the start + * @param count + * the count + * @param fetchRelation + * the fetch relation + * @return the list + */ + + Map search(String luceneQuery, int start, int count, boolean fetchRelation); + + boolean entityExistsInIndex(Class entityClass); + + /** + * Close on index writer/reader. + */ + void close(); + + /** + * Flushes out indexes. + */ + void flush(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/NodeStateContext.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/NodeStateContext.java new file mode 100644 index 000000000..0aa557363 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/NodeStateContext.java @@ -0,0 +1,126 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle; + +import java.util.Map; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.NodeLink; +import com.impetus.kundera.lifecycle.states.NodeState; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.persistence.context.PersistenceCache; +import com.impetus.kundera.persistence.event.EntityEventDispatcher; + +/** + * State context of a given entity + * + * @author amresh + * + */ +public interface NodeStateContext +{ + // State methods + NodeState getCurrentNodeState(); + + void setCurrentNodeState(NodeState nodeState); + + String getNodeId(); + + void setNodeId(String nodeId); + + Object getData(); + + void setData(Object data); + + Class getDataClass(); + + void setDataClass(Class dataClass); + + Map getParents(); + + void setParents(Map parents); + + Map getChildren(); + + void setChildren(Map children); + + Node getParentNode(String parentNodeId); + + Node getChildNode(String childNodeId); + + void addParentNode(NodeLink nodeLink, Node node); + + void addChildNode(NodeLink nodeLink, Node node); + + boolean isTraversed(); + + void setTraversed(boolean traversed); + + boolean isDirty(); + + void setDirty(boolean dirty); + + boolean isHeadNode(); + + Client getClient(); + + void setClient(Client client); + + PersistenceDelegator getPersistenceDelegator(); + + void setPersistenceDelegator(PersistenceDelegator pd); + + // Life cycle Management + void persist(); + + void remove(); + + void refresh(); + + void merge(); + + void detach(); + + void close(); + + void lock(); + + void commit(); + + void rollback(); + + // Identity Management + void find(); + + void getReference(); + + void contains(); + + // Cache Management + void clear(); + + void flush(); + + public boolean isInState(Class stateClass); + + public PersistenceCache getPersistenceCache(); + + public void setPersistenceCache(PersistenceCache persistenceCache); + + public Object getEntityId(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/DetachedState.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/DetachedState.java new file mode 100644 index 000000000..7210ac056 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/DetachedState.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle.states; + +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.lifecycle.NodeStateContext; + +/** + * @author amresh + * + */ +public class DetachedState extends NodeState +{ + + @Override + public void initialize(NodeStateContext nodeStateContext) + { + } + + @Override + public void handlePersist(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException("Persist operation not allowed in Detached state"); + } + + @Override + public void handleRemove(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException( + "Remove operation not allowed in Detached state." + + " Possible reason: You may have closed entity manager before calling remove. A solution is to call merge before remove."); + } + + @Override + public void handleRefresh(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException("Refresh operation not allowed in Detached state"); + } + + @Override + public void handleMerge(NodeStateContext nodeStateContext) + { + // Detached ---> Managed + moveNodeToNextState(nodeStateContext, new ManagedState()); + + ((Node) nodeStateContext).setUpdate(true); + + // Copy detached entity's current state to existing managed instance of + // the + // same entity identity (if one exists), or create a new managed copy + + // Cascade manage operation for all related entities for whom + // cascade=ALL or MERGE + recursivelyPerformOperation(nodeStateContext, OPERATION.MERGE); + } + + @Override + public void handleFind(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleClose(NodeStateContext nodeStateContext) + { + // Nothing to do, already in Detached State + } + + @Override + public void handleClear(NodeStateContext nodeStateContext) + { + // Nothing to do, already in Detached State + } + + @Override + public void handleFlush(NodeStateContext nodeStateContext) + { + // Nothing to do, Entities are flushed from Managed/ Removed state only + } + + @Override + public void handleLock(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleDetach(NodeStateContext nodeStateContext) + { + // Nothing to do, already in Detached State + } + + @Override + public void handleCommit(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleRollback(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleGetReference(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleContains(NodeStateContext nodeStateContext) + { + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/ManagedState.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/ManagedState.java new file mode 100644 index 000000000..4e52e9205 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/ManagedState.java @@ -0,0 +1,243 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle.states; + +import javax.persistence.PersistenceContextType; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.lifecycle.NodeStateContext; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.EntityReader; + +/** + * @author amresh + * + */ +public class ManagedState extends NodeState +{ + + @Override + public void initialize(NodeStateContext nodeStateContext) + { + + } + + @Override + public void handlePersist(NodeStateContext nodeStateContext) + { + // Ignored, entity remains in the same state + + // Cascade persist operation for related entities for whom cascade=ALL + // or PERSIST + recursivelyPerformOperation(nodeStateContext, OPERATION.PERSIST); + } + + @Override + public void handleRemove(NodeStateContext nodeStateContext) + { + // Managed ---> Removed + moveNodeToNextState(nodeStateContext, new RemovedState()); + + // Mark entity for removal in persistence context + nodeStateContext.setDirty(true); + + // Recurse remove operation for all related entities for whom + // cascade=ALL or REMOVE + recursivelyPerformOperation(nodeStateContext, OPERATION.REMOVE); + } + + @Override + public void handleRefresh(NodeStateContext nodeStateContext) + { + // Refresh entity state from the database + // Fetch Node data from Client + Client client = nodeStateContext.getClient(); + Class nodeDataClass = nodeStateContext.getDataClass(); + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(nodeDataClass); + Object entityId = nodeStateContext.getEntityId(); + + EntityReader reader = client.getReader(); + EnhanceEntity ee = reader.findById(entityId, entityMetadata, client); + + if (ee != null && ee.getEntity() != null) + { + Object nodeData = ee.getEntity(); + nodeStateContext.setData(nodeData); + } + + // Cascade refresh operation for all related entities for whom + // cascade=ALL or REFRESH + recursivelyPerformOperation(nodeStateContext, OPERATION.REFRESH); + } + + @Override + public void handleMerge(NodeStateContext nodeStateContext) + { + // Ignored, entity remains in the same state + + // Mark this entity for saving in database depending upon whether it's + // deep equals to the + // one in persistence cache + // nodeStateContext.setDirty(true); + + ((Node) nodeStateContext).setUpdate(true); + // Add this node into persistence cache + nodeStateContext.getPersistenceCache().getMainCache().addNodeToCache((Node) nodeStateContext); + + // Cascade merge operation for all related entities for whom cascade=ALL + // or MERGE + recursivelyPerformOperation(nodeStateContext, OPERATION.MERGE); + } + + @Override + public void handleFind(NodeStateContext nodeStateContext) + { + // Fetch Node data from Client + Client client = nodeStateContext.getClient(); + Class nodeDataClass = nodeStateContext.getDataClass(); + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(nodeDataClass); + Object entityId = nodeStateContext.getEntityId(); + + Object nodeData = null; // Node data + + EntityReader reader = client.getReader(); + if (reader == null) + { + return; + } + + EnhanceEntity ee = reader.findById(entityId, entityMetadata, client); + // Recursively retrieve relationship entities (if there are any) + if (ee != null && ee.getEntity() != null) + { + Object entity = ee.getEntity(); + + if ((entityMetadata.getRelationNames() == null || entityMetadata.getRelationNames().isEmpty()) + && !entityMetadata.isRelationViaJoinTable()) + { + // There is no relation (not even via Join Table), Construct + // Node out of this enhance entity, + nodeData = entity; + } + + else + { + // This entity has associated entities, find them recursively. + nodeData = reader.recursivelyFindEntities(ee.getEntity(), ee.getRelations(), entityMetadata, + nodeStateContext.getPersistenceDelegator(),false); + } + } + + // Construct Node out of this entity and put into Persistence Cache + if (nodeData != null) + { + + nodeStateContext.setData(nodeData); + nodeStateContext.getPersistenceCache().getMainCache().processNodeMapping((Node) nodeStateContext); + + // This node is fresh and hence NOT dirty + nodeStateContext.setDirty(false); + // One time set as required for rollback. + Object original = ((Node) nodeStateContext).clone(); + ((Node) nodeStateContext).setOriginalNode((Node) original); + } + + // No state change, Node to remain in Managed state + } + + @Override + public void handleClose(NodeStateContext nodeStateContext) + { + handleDetach(nodeStateContext); + } + + @Override + public void handleClear(NodeStateContext nodeStateContext) + { + handleDetach(nodeStateContext); + } + + @Override + public void handleFlush(NodeStateContext nodeStateContext) + { + // Entity state to remain as Managed + + // Flush this node to database + Client client = nodeStateContext.getClient(); + client.persist((Node) nodeStateContext); + + // logNodeEvent("FLUSHED", this, nodeStateContext.getNodeId()); + + // Since node is flushed, mark it as NOT dirty + nodeStateContext.setDirty(false); + + } + + @Override + public void handleLock(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleDetach(NodeStateContext nodeStateContext) + { + // Managed ---> Detached + moveNodeToNextState(nodeStateContext, new DetachedState()); + + // Cascade detach operation to all referenced entities for whom + // cascade=ALL or DETACH + recursivelyPerformOperation(nodeStateContext, OPERATION.DETACH); + } + + @Override + public void handleCommit(NodeStateContext nodeStateContext) + { + nodeStateContext.setCurrentNodeState(new DetachedState()); + } + + @Override + public void handleRollback(NodeStateContext nodeStateContext) + { + // If persistence context is EXTENDED, Next state should be Transient + // If persistence context is TRANSACTIONAL, Next state should be + // detached + + if (PersistenceContextType.EXTENDED.equals(nodeStateContext.getPersistenceCache().getPersistenceContextType())) + { + moveNodeToNextState(nodeStateContext, new TransientState()); + + } + else if (PersistenceContextType.TRANSACTION.equals(nodeStateContext.getPersistenceCache() + .getPersistenceContextType())) + { + moveNodeToNextState(nodeStateContext, new DetachedState()); + } + } + + @Override + public void handleGetReference(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleContains(NodeStateContext nodeStateContext) + { + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/NodeState.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/NodeState.java new file mode 100644 index 000000000..650d7cf70 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/NodeState.java @@ -0,0 +1,138 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle.states; + +import java.util.List; +import java.util.Map; + +import javax.persistence.CascadeType; + +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.NodeLink; +import com.impetus.kundera.graph.NodeLink.LinkProperty; +import com.impetus.kundera.lifecycle.NodeStateContext; + +/** + * State machine class for Node state + * + * @author amresh + * + */ +public abstract class NodeState +{ + public enum OPERATION + { + PERSIST, MERGE, REMOVE, REFRESH, DETACH + } + + public abstract void initialize(NodeStateContext nodeStateContext); + + // Life cycle Management + public abstract void handlePersist(NodeStateContext nodeStateContext); + + public abstract void handleRemove(NodeStateContext nodeStateContext); + + public abstract void handleRefresh(NodeStateContext nodeStateContext); + + public abstract void handleMerge(NodeStateContext nodeStateContext); + + public abstract void handleDetach(NodeStateContext nodeStateContext); + + public abstract void handleClose(NodeStateContext nodeStateContext); + + public abstract void handleLock(NodeStateContext nodeStateContext); + + public abstract void handleCommit(NodeStateContext nodeStateContext); + + public abstract void handleRollback(NodeStateContext nodeStateContext); + + // Identity Management + public abstract void handleFind(NodeStateContext nodeStateContext); + + public abstract void handleGetReference(NodeStateContext nodeStateContext); + + public abstract void handleContains(NodeStateContext nodeStateContext); + + // Cache Management + public abstract void handleClear(NodeStateContext nodeStateContext); + + public abstract void handleFlush(NodeStateContext nodeStateContext); + + /** + * @param nodeStateContext + */ + void moveNodeToNextState(NodeStateContext nodeStateContext, NodeState nextState) + { + nodeStateContext.setCurrentNodeState(nextState); + } + + /** + * @param nodeStateContext + */ + void recursivelyPerformOperation(NodeStateContext nodeStateContext, OPERATION operation) + { + Map children = nodeStateContext.getChildren(); + if (children != null) + { + for (NodeLink nodeLink : children.keySet()) + { + List cascadeTypes = (List) nodeLink.getLinkProperty(LinkProperty.CASCADE); + + switch (operation) + { + case PERSIST: + if (cascadeTypes.contains(CascadeType.PERSIST) || cascadeTypes.contains(CascadeType.ALL)) + { + Node childNode = children.get(nodeLink); + childNode.persist(); + } + break; + case MERGE: + if (cascadeTypes.contains(CascadeType.MERGE) || cascadeTypes.contains(CascadeType.ALL)) + { + Node childNode = children.get(nodeLink); + childNode.merge(); + } + break; + + case REMOVE: + if (cascadeTypes.contains(CascadeType.REMOVE) || cascadeTypes.contains(CascadeType.ALL)) + { + Node childNode = children.get(nodeLink); + childNode.remove(); + } + break; + + case REFRESH: + if (cascadeTypes.contains(CascadeType.REFRESH) || cascadeTypes.contains(CascadeType.ALL)) + { + Node childNode = children.get(nodeLink); + childNode.refresh(); + } + break; + case DETACH: + if (cascadeTypes.contains(CascadeType.DETACH) || cascadeTypes.contains(CascadeType.ALL)) + { + Node childNode = children.get(nodeLink); + childNode.detach(); + } + break; + } + + } + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/RemovedState.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/RemovedState.java new file mode 100644 index 000000000..9c993a30c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/RemovedState.java @@ -0,0 +1,157 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle.states; + +import javax.persistence.PersistenceContextType; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.lifecycle.NodeStateContext; + +/** + * @author amresh + * + */ +public class RemovedState extends NodeState +{ + @Override + public void initialize(NodeStateContext nodeStateContext) + { + } + + @Override + public void handlePersist(NodeStateContext nodeStateContext) + { + // Removed ---> Managed State + moveNodeToNextState(nodeStateContext, new ManagedState()); + + // Recurse persist operation on all related entities for whom + // cascade=ALL or PERSIST + recursivelyPerformOperation(nodeStateContext, OPERATION.PERSIST); + } + + @Override + public void handleRemove(NodeStateContext nodeStateContext) + { + // Ignored, entity will remain in removed state + + // Recurse remove operation for all related entities for whom + // cascade=ALL or REMOVE + recursivelyPerformOperation(nodeStateContext, OPERATION.REMOVE); + } + + @Override + public void handleRefresh(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException("Refresh operation not allowed in Removed state"); + } + + @Override + public void handleMerge(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException("Merge operation not allowed in Removed state"); + } + + @Override + public void handleFind(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleClose(NodeStateContext nodeStateContext) + { + // Nothing to do, only entities in Managed state move to detached state + } + + @Override + public void handleClear(NodeStateContext nodeStateContext) + { + // Nothing to do, only entities in Managed state move to detached state + } + + @Override + public void handleFlush(NodeStateContext nodeStateContext) + { + // Entity state to remain as Removed + + // Flush this node to database + Client client = nodeStateContext.getClient(); + + Node node = (Node) nodeStateContext; + + Object entityId = node.getEntityId(); + + client.delete(node.getData(), entityId); + + // Since node is flushed, mark it as NOT dirty + nodeStateContext.setDirty(false); + + // Remove this node from Persistence Cache + nodeStateContext.getPersistenceCache().getMainCache().removeNodeFromCache(node); + } + + @Override + public void handleLock(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleDetach(NodeStateContext nodeStateContext) + { + // Removed ---> Detached + moveNodeToNextState(nodeStateContext, new DetachedState()); + + // Cascade detach operation to all referenced entities for whom + // cascade=ALL or DETACH + recursivelyPerformOperation(nodeStateContext, OPERATION.DETACH); + } + + @Override + public void handleCommit(NodeStateContext nodeStateContext) + { + nodeStateContext.setCurrentNodeState(new TransientState()); + } + + @Override + public void handleRollback(NodeStateContext nodeStateContext) + { + // If persistence context is EXTENDED, Next state should be Managed + // If persistence context is TRANSACTIONAL, Node should be detached + + if (PersistenceContextType.EXTENDED.equals(nodeStateContext.getPersistenceCache().getPersistenceContextType())) + { + moveNodeToNextState(nodeStateContext, new ManagedState()); + + } + else if (PersistenceContextType.TRANSACTION.equals(nodeStateContext.getPersistenceCache() + .getPersistenceContextType())) + { + nodeStateContext.detach(); + } + + } + + @Override + public void handleGetReference(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleContains(NodeStateContext nodeStateContext) + { + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/TransientState.java b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/TransientState.java new file mode 100644 index 000000000..98a8e5c0a --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/lifecycle/states/TransientState.java @@ -0,0 +1,134 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.lifecycle.states; + +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.lifecycle.NodeStateContext; +import com.impetus.kundera.utils.ObjectUtils; + +/** + * @author amresh + * + */ +public class TransientState extends NodeState +{ + @Override + public void initialize(NodeStateContext nodeStateContext) + { + } + + @Override + public void handlePersist(NodeStateContext nodeStateContext) + { + + // Transient ---> Managed + moveNodeToNextState(nodeStateContext, new ManagedState()); + + // Mark this entity for saving in database + nodeStateContext.setDirty(true); + + // Add this node into persistence cache + nodeStateContext.getPersistenceCache().getMainCache().addNodeToCache((Node) nodeStateContext); + + // Recurse persist operation on all managed entities for whom + // cascade=ALL or PERSIST + recursivelyPerformOperation(nodeStateContext, OPERATION.PERSIST); + } + + @Override + public void handleRemove(NodeStateContext nodeStateContext) + { + // Ignored, Entity will remain in the Transient state + + // Recurse remove operation for all related entities for whom + // cascade=ALL or REMOVE + recursivelyPerformOperation(nodeStateContext, OPERATION.REMOVE); + } + + @Override + public void handleRefresh(NodeStateContext nodeStateContext) + { + throw new IllegalArgumentException("Refresh operation not allowed in Transient state"); + } + + @Override + public void handleMerge(NodeStateContext nodeStateContext) + { + // create a new managed entity and copy state of original entity into + // this one. + Object copiedNodeData = ObjectUtils.deepCopy(nodeStateContext.getData()); + nodeStateContext.setData(copiedNodeData); + } + + @Override + public void handleFind(NodeStateContext nodeStateContext) + { + // Nothing to do, Entity once found, jusmps directly to managed state + } + + @Override + public void handleClose(NodeStateContext nodeStateContext) + { + // Nothing to do, only entities in Managed/ Removed state move to + // detached state + } + + @Override + public void handleClear(NodeStateContext nodeStateContext) + { + // Nothing to do, only entities in Managed/ Removed state move to + // detached state + } + + @Override + public void handleFlush(NodeStateContext nodeStateContext) + { + // Nothing to do, Entities are flushed from Managed/ Removed state only + } + + @Override + public void handleLock(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleDetach(NodeStateContext nodeStateContext) + { + // Nothing to do, only entities in Managed/ Removed state move to + // detached state + } + + @Override + public void handleCommit(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleRollback(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleGetReference(NodeStateContext nodeStateContext) + { + } + + @Override + public void handleContains(NodeStateContext nodeStateContext) + { + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientFactory.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientFactory.java new file mode 100644 index 000000000..591e3fdbf --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientFactory.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import java.util.Map; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.schema.api.SchemaManager; + +/** + * Interface for client factory. + * + * @author vivek.mishra + * + */ +public interface ClientFactory +{ + + /** + * Load. + * + * @param persistenceUnit + * the persistence units + */ + void load(String persistenceUnit, Map puProperties); + + /** + * Instantiate and returns client instance + * + * @return client instance. + */ + Client getClientInstance(); + + /** + * return the instance of schema manager + * + * @return schemaManager interface. + */ + SchemaManager getSchemaManager(Map puProperties); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLifeCycleManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLifeCycleManager.java new file mode 100644 index 000000000..f64a5ba7e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLifeCycleManager.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import java.util.Map; + +/** + * Interface to define for client life cycle manager. + * + * @author vivek.mishra + * + */ +public interface ClientLifeCycleManager +{ + + /** + * Initialize configured client. + */ + void initialize(Map puProperties); + + /** + * Returns true if client is thread safe, else false. + * + * @return true if client is thread safe. + */ + boolean isThreadSafe(); + + /** + * Unloads/destroy configured client instance. + */ + void destroy(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLoaderException.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLoaderException.java new file mode 100644 index 000000000..b60ff81bd --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/ClientLoaderException.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh.singh + * + */ +public class ClientLoaderException extends KunderaException +{ + + /** + * + */ + private static final long serialVersionUID = -2780499169457052865L; + + /** + * + */ + public ClientLoaderException() + { + } + + /** + * @param arg0 + */ + public ClientLoaderException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public ClientLoaderException(Throwable arg0) + { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public ClientLoaderException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/CoreLoader.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/CoreLoader.java new file mode 100644 index 000000000..be0341609 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/CoreLoader.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.model.CoreMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.proxy.cglib.CglibLazyInitializerFactory; + +/** + * The Class CoreLoader. + * + * @author amresh.singh + */ +public class CoreLoader +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(CoreLoader.class); + + /** + * Load. + */ + public void load() + { + log.info("Loading Kundera Core Metdata ... "); + + CoreMetadata coreMetadata = new CoreMetadata(); + coreMetadata.setLazyInitializerFactory(new CglibLazyInitializerFactory()); + KunderaMetadata.INSTANCE.setCoreMetadata(coreMetadata); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/GenericClientFactory.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/GenericClientFactory.java new file mode 100644 index 000000000..76e99621e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/GenericClientFactory.java @@ -0,0 +1,339 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.commons.lang.StringUtils; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.util.Version; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.PropertyReader; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.index.Indexer; +import com.impetus.kundera.index.LuceneIndexer; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.service.Host; +import com.impetus.kundera.service.policy.LoadBalancingPolicy; +import com.impetus.kundera.service.policy.RetryService; +import com.impetus.kundera.service.policy.RoundRobinBalancingPolicy; + +/** + * Abstract class to hold generic definitions for client factory + * implementations. + * + * @author vivek.mishra + */ +public abstract class GenericClientFactory implements ClientFactory, ClientLifeCycleManager +{ + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(GenericClientFactory.class); + + /** The client. */ + private Client client; + + /** The persistence unit. */ + private String persistenceUnit; + + /** The connection pool or connection. */ + private Object connectionPoolOrConnection; + + /** The index manager. */ + protected IndexManager indexManager = new IndexManager(null); + + /** The reader. */ + protected EntityReader reader; + + /** Configure schema manager. */ + protected SchemaManager schemaManager; + + /** property reader instance */ + protected PropertyReader propertyReader; + + /** Holds persistence unit related property */ + protected Map externalProperties = new HashMap(); + + /** Holds LoadBalancer instance **/ + protected LoadBalancingPolicy loadBalancingPolicy = new RoundRobinBalancingPolicy(); + + /** Holds Instance of retry service */ + protected RetryService hostRetryService; + + /** Holds one pool instance per host */ + protected ConcurrentMap hostPools = new ConcurrentHashMap(); + + /** + * Holds reference to client metadata. + */ + protected ClientMetadata clientMetadata; + + /** + * Load. + * + * @param persistenceUnit + * the persistence unit + */ + @Override + public void load(String persistenceUnit, Map puProperties) + { + setPersistenceUnit(persistenceUnit); + + // Load Client Specific Stuff + logger.info("Loading client metadata for persistence unit : " + persistenceUnit); + loadClientMetadata(puProperties); + + // initialize the client + logger.info("Initializing client for persistence unit : " + persistenceUnit); + initialize(puProperties); + + // Construct Pool + logger.info("Constructing pool for persistence unit : " + persistenceUnit); + connectionPoolOrConnection = createPoolOrConnection(); + } + + /** + * Load client metadata. + * + * @param puProperties + */ + protected void loadClientMetadata(Map puProperties) + { + clientMetadata = new ClientMetadata(); + String luceneDirectoryPath = puProperties != null ? (String) puProperties + .get(PersistenceProperties.KUNDERA_INDEX_HOME_DIR) : null; + + String indexerClass = puProperties != null ? (String) puProperties + .get(PersistenceProperties.KUNDERA_INDEXER_CLASS) : null; + + if (indexerClass == null) + { + indexerClass = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit).getProperties() + .getProperty(PersistenceProperties.KUNDERA_INDEXER_CLASS); + } + + if (luceneDirectoryPath == null) + { + luceneDirectoryPath = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(persistenceUnit) + .getProperty(PersistenceProperties.KUNDERA_INDEX_HOME_DIR); + } + + // in case set empty via external property, means want to avoid lucene directory set up. + if (luceneDirectoryPath != null && !StringUtils.isEmpty(luceneDirectoryPath)) + { + // Add client metadata + clientMetadata.setLuceneIndexDir(luceneDirectoryPath); + + // Set Index Manager + indexManager = new IndexManager(LuceneIndexer.getInstance(new StandardAnalyzer(Version.LUCENE_34), + luceneDirectoryPath)); + } + else if (indexerClass != null) + { + try + { + Class indexerClazz = Class.forName(indexerClass); + Indexer indexer = (Indexer) indexerClazz.newInstance(); + indexManager = new IndexManager(indexer); + clientMetadata.setIndexImplementor(indexerClass); + } + catch (Exception cnfex) + { + logger.error("Error while initialzing indexer:" + indexerClass, cnfex); + throw new KunderaException(cnfex); + } + } + else + { + indexManager = new IndexManager(null); + } +// if (KunderaMetadata.INSTANCE.getClientMetadata(persistenceUnit) == null) +// { +// KunderaMetadata.INSTANCE.addClientMetadata(persistenceUnit, clientMetadata); +// } + } + + /** + * Initialize client. + * + * @param puProperties + */ + public abstract void initialize(Map puProperties); + + /** + * Creates a new GenericClient object. + * + * @param externalProperties + * + * @return the object + */ + protected abstract Object createPoolOrConnection(); + + /** + * Gets the client instance. + * + * @return the client instance + */ + @Override + public Client getClientInstance() + { + // if threadsafe recycle the same single instance; if not create a new + // instance + + if (isThreadSafe()) + { + logger.info("Returning threadsafe used client instance for persistence unit : " + persistenceUnit); + if (client == null) + { + client = instantiateClient(persistenceUnit); + } + } + else + { + logger.debug("Returning fresh client instance for persistence unit : " + persistenceUnit); + // no need to hold a client reference. + return instantiateClient(persistenceUnit); + } + + return client; + } + + /** + * Instantiate client. + * + * @return the client + */ + protected abstract Client instantiateClient(String persistenceUnit); + + /** + * Checks if is client thread safe. + * + * @return true, if is client thread safe + */ + public abstract boolean isThreadSafe(); + + /** + * Gets the persistence unit. + * + * @return the persistence unit + */ + protected String getPersistenceUnit() + { + return persistenceUnit; + } + + /** + * Gets the connection pool or connection. + * + * @return the connection pool or connection + */ + protected Object getConnectionPoolOrConnection() + { + return connectionPoolOrConnection; + } + + /** + * Sets the connection pool or connection. + */ + protected void setConnectionPoolOrConnection(Object connectionPoolOrConnection) + { + this.connectionPoolOrConnection = connectionPoolOrConnection; + } + + /** + * Sets the persistence unit. + * + * @param persistenceUnit + * the new persistence unit + */ + private void setPersistenceUnit(String persistenceUnit) + { + this.persistenceUnit = persistenceUnit; + } + + /** + * @param puProperties + */ + protected void setExternalProperties(Map puProperties) + { + if (puProperties != null) + { + this.externalProperties = puProperties; + } + } + + protected void onValidation(final String host, final String port) + { + if (host == null || !StringUtils.isNumeric(port) || port.isEmpty()) + { + logger.error("Host or port should not be null / port should be numeric"); + throw new IllegalArgumentException("Host or port should not be null / port should be numeric"); + } + } + + protected void unload() + { + if (client != null) + { + client.close(); + client = null; + } + externalProperties = null; + hostPools.clear(); + } + + protected abstract void initializeLoadBalancer(String loadBalancingPolicyName); + + public ClientMetadata getClientMetadata() + { + return this.clientMetadata; + } + + protected enum LoadBalancer + { + ROUNDROBIN, LEASTACTIVE; + + public static LoadBalancer getValue(String loadBalancename) + { + if (loadBalancename != null && loadBalancename.equalsIgnoreCase(ROUNDROBIN.name())) + { + return ROUNDROBIN; + } + else if (loadBalancename != null && loadBalancename.equalsIgnoreCase(LEASTACTIVE.name())) + { + return LEASTACTIVE; + } + else + { + logger.info("Using default load balancer {} . " + ROUNDROBIN.name()); + return ROUNDROBIN; + } + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/KunderaAuthenticationException.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/KunderaAuthenticationException.java new file mode 100644 index 000000000..97549a555 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/KunderaAuthenticationException.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import com.impetus.kundera.KunderaException; + +/** + * @author vivek.mishra + * + */ +public class KunderaAuthenticationException extends KunderaException +{ + + /** + * + */ + private static final long serialVersionUID = -708462011401566049L; + + /** + * + */ + public KunderaAuthenticationException() + { + } + + /** + * @param arg0 + */ + public KunderaAuthenticationException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public KunderaAuthenticationException(Throwable arg0) + { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public KunderaAuthenticationException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/MetamodelLoaderException.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/MetamodelLoaderException.java new file mode 100644 index 000000000..aaa45e5f2 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/MetamodelLoaderException.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh.singh + * + */ +public class MetamodelLoaderException extends KunderaException +{ + + /** + * + */ + public MetamodelLoaderException() + { + } + + /** + * @param arg0 + */ + public MetamodelLoaderException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public MetamodelLoaderException(Throwable arg0) + { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public MetamodelLoaderException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceLoaderException.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceLoaderException.java new file mode 100644 index 000000000..3383eb927 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceLoaderException.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh.singh + * + */ +public class PersistenceLoaderException extends KunderaException +{ + + /** + * + */ + private static final long serialVersionUID = -8108190222765147635L; + + /** + * + */ + public PersistenceLoaderException() + { + } + + /** + * @param arg0 + */ + public PersistenceLoaderException(String arg0) + { + super(arg0); + + } + + /** + * @param arg0 + */ + public PersistenceLoaderException(Throwable arg0) + { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public PersistenceLoaderException(String arg0, Throwable arg1) + { + super(arg0, arg1); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceXMLLoader.java b/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceXMLLoader.java new file mode 100644 index 000000000..47aded79c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/loader/PersistenceXMLLoader.java @@ -0,0 +1,631 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.loader; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.PersistenceException; +import javax.persistence.spi.PersistenceUnitTransactionType; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.utils.InvalidConfigurationException; + +/** + * The Class PersistenceXMLLoader. + * + * @author amresh.singh + */ +public class PersistenceXMLLoader +{ + /** The log. */ + private static Logger log = LoggerFactory.getLogger(PersistenceXMLLoader.class); + + /** + * Instantiates a new persistence xml loader. + */ + private PersistenceXMLLoader() + { + } + + /** + * Gets the document. + * + * @param configURL + * the config url + * @return the document + * @throws Exception + * the exception + */ + private static Document getDocument(URL configURL) throws InvalidConfigurationException + { + InputStream is = null; + Document doc; + try + { + is = null; + if (configURL != null) + { + URLConnection conn = configURL.openConnection(); + conn.setUseCaches(false); // avoid JAR locking on Windows and + // Tomcat + is = conn.getInputStream(); + } + if (is == null) + { + throw new IOException("Failed to obtain InputStream from url: " + configURL); + } + + DocumentBuilderFactory docBuilderFactory = null; + docBuilderFactory = DocumentBuilderFactory.newInstance(); + docBuilderFactory.setNamespaceAware(true); + + final Schema v2Schema = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( + new StreamSource(getStreamFromClasspath("persistence_2_0.xsd"))); + final Validator v2Validator = v2Schema.newValidator(); + final Schema v1Schema = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( + new StreamSource(getStreamFromClasspath("persistence_1_0.xsd"))); + final Validator v1Validator = v1Schema.newValidator(); + + InputSource source = new InputSource(is); + DocumentBuilder docBuilder = null; + try + { + docBuilder = docBuilderFactory.newDocumentBuilder(); + } + catch (ParserConfigurationException e) + { + log.error("Error during parsing, Caused by: " + e.getMessage()); + throw new PersistenceLoaderException(e); + } + + List errors = new ArrayList(); + docBuilder.setErrorHandler(new ErrorLogger("XML InputStream", errors)); + doc = docBuilder.parse(source); + + if (errors.size() == 0) + { + v2Validator.setErrorHandler(new ErrorLogger("XML InputStream", errors)); + v2Validator.validate(new DOMSource(doc)); + boolean isV1Schema = false; + if (errors.size() != 0) + { + // v2 fails, it could be because the file is v1. + Exception exception = (Exception) errors.get(0); + final String errorMessage = exception.getMessage(); + // is it a validation error due to a v1 schema validated by + // a v2 + isV1Schema = errorMessage.contains("1.0") && errorMessage.contains("2.0") + && errorMessage.contains("version"); + } + if (isV1Schema) + { + errors.clear(); + v1Validator.setErrorHandler(new ErrorLogger("XML InputStream", errors)); + v1Validator.validate(new DOMSource(doc)); + } + } + else + { + throw new InvalidConfigurationException("invalid persistence.xml", (Throwable) errors.get(0)); + } + } + catch (IOException e) + { + throw new InvalidConfigurationException(e); + } + catch (SAXException e) + { + throw new InvalidConfigurationException(e); + } + finally + { + try + { + if (is != null) + { + is.close(); + } + } + catch (IOException e) + { + throw new InvalidConfigurationException(e); + } + } + + return doc; + } + + /** + * Get stream from classpath. + * + * @param fileName + * the file name + * @return the stream + * @throws Exception + * the exception + */ + private static InputStream getStreamFromClasspath(String fileName) + { + String path = fileName; + InputStream dtdStream = PersistenceXMLLoader.class.getClassLoader().getResourceAsStream(path); + return dtdStream; + } + + /** + * Find persistence units. + * + * @param url + * the url + * @return the list + * @throws Exception + * the exception + */ + public static List findPersistenceUnits(URL url) throws Exception + { + return findPersistenceUnits(url, PersistenceUnitTransactionType.JTA); + } + + /** + * Find persistence units. + * + * @param url + * the url + * @param defaultTransactionType + * the default transaction type + * @return the list + * @throws Exception + * the exception + */ + public static List findPersistenceUnits(final URL url, + PersistenceUnitTransactionType defaultTransactionType) throws InvalidConfigurationException + { + + Document doc; + try + { + doc = getDocument(url); + } + catch (InvalidConfigurationException e) + { + throw e; + } + doc.getXmlVersion(); + Element top = doc.getDocumentElement(); + + String versionName = top.getAttribute("version"); + + NodeList children = top.getChildNodes(); + ArrayList units = new ArrayList(); + + // parse for persistenceUnitRootInfoURL. + for (int i = 0; i < children.getLength(); i++) + { + if (children.item(i).getNodeType() == Node.ELEMENT_NODE) + { + Element element = (Element) children.item(i); + String tag = element.getTagName(); + // look for "persistence-unit" element + if (tag.equals("persistence-unit")) + { + PersistenceUnitMetadata metadata = parsePersistenceUnit(url, element, versionName); + // metadata.setPersistenceUnitRootUrl(getPersistenceRootUrl(url)); + units.add(metadata); + } + } + } + return units; + } + + /** + * Parses the persistence unit. + * + * @param top + * the top + * @return the persistence metadata + * @throws Exception + * the exception + */ + private static PersistenceUnitMetadata parsePersistenceUnit(final URL url, Element top, final String versionName) + { + PersistenceUnitMetadata metadata = new PersistenceUnitMetadata(versionName, getPersistenceRootUrl(url), url); + + String puName = top.getAttribute("name"); + if (!isEmpty(puName)) + { + log.trace("Persistent Unit name from persistence.xml: " + puName); + metadata.setPersistenceUnitName(puName); + String transactionType = top.getAttribute("transaction-type"); + if (StringUtils.isEmpty(transactionType) + || PersistenceUnitTransactionType.RESOURCE_LOCAL.name().equals(transactionType)) + { + + metadata.setTransactionType(PersistenceUnitTransactionType.RESOURCE_LOCAL); + + } + else if (PersistenceUnitTransactionType.JTA.name().equals(transactionType)) + { + metadata.setTransactionType(PersistenceUnitTransactionType.JTA); + } + } + + NodeList children = top.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) + { + if (children.item(i).getNodeType() == Node.ELEMENT_NODE) + { + Element element = (Element) children.item(i); + String tag = element.getTagName(); + + if (tag.equals("provider")) + { + metadata.setProvider(getElementContent(element)); + } + + /* + * else if (tag.equals("transaction-type")) { String + * transactionType = getElementContent(element); + * + * if (StringUtils.isEmpty(transactionType) || + * PersistenceUnitTransactionType + * .RESOURCE_LOCAL.name().equals(transactionType)) { + * + * metadata.setTransactionType(PersistenceUnitTransactionType. + * RESOURCE_LOCAL); + * + * } else if + * (PersistenceUnitTransactionType.JTA.name().equals(transactionType + * )) { + * metadata.setTransactionType(PersistenceUnitTransactionType + * .JTA); } + * + * } + */else if (tag.equals("properties")) + { + NodeList props = element.getChildNodes(); + for (int j = 0; j < props.getLength(); j++) + { + if (props.item(j).getNodeType() == Node.ELEMENT_NODE) + { + Element propElement = (Element) props.item(j); + // if element is not "property" then skip + if (!"property".equals(propElement.getTagName())) + { + continue; + } + + String propName = propElement.getAttribute("name").trim(); + String propValue = propElement.getAttribute("value").trim(); + if (isEmpty(propValue)) + { + propValue = getElementContent(propElement, ""); + } + metadata.getProperties().put(propName, propValue); + } + } + } + // Kundera doesn't support "class", "jar-file" and + // "excluded-unlisted-classes" for now.. but will someday. + // let's parse it for now. + else if (tag.equals("class")) + { + metadata.getClasses().add(getElementContent(element)); + } + else if (tag.equals("jar-file")) + { + metadata.addJarFile(getElementContent(element)); + } + else if (tag.equals("exclude-unlisted-classes")) + { + metadata.setExcludeUnlistedClasses(true); + } + } + } + PersistenceUnitTransactionType transactionType = getTransactionType(top.getAttribute("transaction-type")); + if (transactionType != null) + { + metadata.setTransactionType(transactionType); + } + + return metadata; + } + + /** + * Gets the transaction type. + * + * @param elementContent + * the element content + * @return the transaction type + */ + public static PersistenceUnitTransactionType getTransactionType(String elementContent) + { + + if (elementContent == null || elementContent.isEmpty()) + { + return null; + } + else if (elementContent.equalsIgnoreCase("JTA")) + { + return PersistenceUnitTransactionType.JTA; + } + else if (elementContent.equalsIgnoreCase("RESOURCE_LOCAL")) + { + return PersistenceUnitTransactionType.RESOURCE_LOCAL; + } + else + { + throw new PersistenceException("Unknown TransactionType: " + elementContent); + } + } + + /** + * The Class ErrorLogger. + */ + public static class ErrorLogger implements ErrorHandler + { + + /** The file. */ + private String file; + + /** The errors. */ + private List errors; + + /** + * Instantiates a new error logger. + * + * @param file + * the file + * @param errors + * the errors + */ + ErrorLogger(String file, List errors) + { + this.file = file; + this.errors = errors; + } + + /* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) */ + /* + * (non-Javadoc) + * + * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) + */ + public void error(SAXParseException error) + { + log.error("Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage()); + errors.add(error); + } + + /* + * @see + * org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) + */ + /* + * (non-Javadoc) + * + * @see + * org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) + */ + public void fatalError(SAXParseException error) + { + log.error("Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage()); + errors.add(error); + } + + /* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) */ + /* + * (non-Javadoc) + * + * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) + */ + public void warning(SAXParseException warn) + { + log.warn("Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage()); + } + } + + /** + * Checks if is empty. + * + * @param str + * the str + * @return true, if is empty + */ + private static boolean isEmpty(String str) + { + return null == str || str.isEmpty(); + } + + /** + * Gets the element content. + * + * @param element + * the element + * @return the element content + * @throws Exception + * the exception + */ + public static String getElementContent(final Element element) + { + return getElementContent(element, null); + } + + /** + * Get the content of the given element. + * + * @param element + * The element to get the content for. + * @param defaultStr + * The default to return when there is no content. + * @return The content of the element or the default. + * @throws Exception + * the exception + */ + private static String getElementContent(Element element, String defaultStr) + { + if (element == null) + { + return defaultStr; + } + + NodeList children = element.getChildNodes(); + StringBuilder result = new StringBuilder(""); + for (int i = 0; i < children.getLength(); i++) + { + if (children.item(i).getNodeType() == Node.TEXT_NODE + || children.item(i).getNodeType() == Node.CDATA_SECTION_NODE) + { + result.append(children.item(i).getNodeValue()); + } + } + return result.toString().trim(); + } + + /** + * Returns persistence unit root url + * + * @param url + * raw url + * @return rootUrl rootUrl + */ + private static URL getPersistenceRootUrl(URL url) + { + + String f = url.getFile(); + f = parseFilePath(f); + + + String protocol = url.getProtocol(); + + URL jarUrl = url; + try + { + if (AllowedProtocol.isJarProtocol(url.getProtocol())) + { + jarUrl = new URL(f); + if (jarUrl.getProtocol() != null + && AllowedProtocol.FILE.name().equals(jarUrl.getProtocol().toUpperCase()) + && StringUtils.contains(f, " ")) + { + jarUrl = new File(f).toURI().toURL(); + } + } + else if (AllowedProtocol.isValidProtocol(url.getProtocol())) + { + if (StringUtils.contains(f, " ")) + { + jarUrl = new File(f).toURI().toURL(); + } + else + { + jarUrl = new File(f).toURL(); + } + } + } + catch (MalformedURLException mex) + { + log.error("Error during getPersistenceRootUrl(), Caused by: " + mex.getMessage()); + throw new IllegalArgumentException("invalid jar URL[] provided!" + url); + } + + return jarUrl; + } + + /** + * Parse and exclude path till META-INF + * + * @param file + * raw file path. + * @return extracted/parsed file path. + */ + private static String parseFilePath(String file) + { + final String excludePattern = "/META-INF/persistence.xml"; + file = file.substring(0, file.length() - excludePattern.length()); + + // in case protocol is "file". + file = file.endsWith("!") ? file.substring(0, file.length() - 1) : file; + + return file; + } + + /** + * Allowed protocols + */ + public enum AllowedProtocol + { + WSJAR, JAR, ZIP, FILE, VFSZIP,VFS; + + /** + * In case it is jar protocol + * + * @param protocol + * @return + */ + public static boolean isJarProtocol(String protocol) + { + return protocol != null + && (protocol.toUpperCase().equals(JAR.name()) || protocol.toUpperCase().equals(WSJAR.name())); + } + + /** + * If provided protocol is within allowed protocol. + * + * @param protocol + * protocol + * @return true, if it is in allowed protocol. + */ + public static boolean isValidProtocol(String protocol) + { + try + { + AllowedProtocol.valueOf(protocol.toUpperCase()); + return true; + } + catch (IllegalArgumentException iex) + { + return false; + } + } + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/KunderaMetadataManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/KunderaMetadataManager.java new file mode 100644 index 000000000..c0aacff4f --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/KunderaMetadataManager.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * The Class KunderaMetadataManager. + * + * @author amresh.singh + */ +public class KunderaMetadataManager +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(KunderaMetadataManager.class); + + /** + * Gets the persistence unit metadata. + * + * @param persistenceUnit + * the persistence unit + * @return the persistence unit metadata + */ + public static PersistenceUnitMetadata getPersistenceUnitMetadata(String persistenceUnit) + { + if (persistenceUnit != null) + { + return KunderaMetadata.INSTANCE.getApplicationMetadata().getPersistenceUnitMetadata(persistenceUnit); + } + return null; + } + + /** + * Gets the metamodel. + * + * @param persistenceUnit + * the persistence unit + * @return the metamodel + */ + public static MetamodelImpl getMetamodel(String persistenceUnit) + { + KunderaMetadata kunderaMetadata = KunderaMetadata.INSTANCE; + + MetamodelImpl metamodel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata() + .getMetamodel(persistenceUnit); + + return metamodel; + } + + /** + * Gets the metamodel. + * + * @param persistenceUnits + * the persistence units + * @return the metamodel + */ + public static MetamodelImpl getMetamodel(String... persistenceUnits) + { + KunderaMetadata kunderaMetadata = KunderaMetadata.INSTANCE; + + MetamodelImpl metamodel = null; + for (String pu : persistenceUnits) + { + metamodel = (MetamodelImpl) kunderaMetadata.getApplicationMetadata().getMetamodel(pu); + + if (metamodel != null) + { + return metamodel; + } + } + + // FIXME: I need to verify this why we need common entity metadata now! + // if (metamodel == null) + // { + // metamodel = (MetamodelImpl) + // kunderaMetadata.getApplicationMetadata().getMetamodel( + // Constants.COMMON_ENTITY_METADATAS); + // } + return metamodel; + } + + /** + * Gets the entity metadata. + * + * @param persistenceUnit + * the persistence unit + * @param entityClass + * the entity class + * @return the entity metadata + */ + public static EntityMetadata getEntityMetadata(String persistenceUnit, Class entityClass) + { + return getMetamodel(persistenceUnit).getEntityMetadata(entityClass); + } + + /** + * Finds ands returns Entity metadata for a given array of PUs. + * + * @param entityClass + * the entity class + * @param persistenceUnits + * the persistence units + * @return the entity metadata + */ + public static EntityMetadata getEntityMetadata(Class entityClass) + { + if (entityClass == null) + { + throw new KunderaException("Invalid class provided " + entityClass); + } + List persistenceUnits = KunderaMetadata.INSTANCE.getApplicationMetadata().getMappedPersistenceUnit( + entityClass); + + // persistence units will only have more than 1 persistence unit in case + // of RDBMS. + if (persistenceUnits != null) + { + for (String pu : persistenceUnits) + { + MetamodelImpl metamodel = getMetamodel(pu); + EntityMetadata metadata = metamodel.getEntityMetadata(entityClass); + if (metadata != null && metadata.getPersistenceUnit().equals(pu)) + { + return metadata; + } + } + } + if (log.isDebugEnabled()) + log.warn("No Entity metadata found for the class " + entityClass + + ". Any CRUD operation on this entity will fail." + + "If your entity is for RDBMS, make sure you put fully qualified entity class" + + " name under tag in persistence.xml for RDBMS " + + "persistence unit. Returning null value."); + + return null; + // throw new KunderaException("Unable to load entity metadata for :" + + // entityClass); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataBuilder.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataBuilder.java new file mode 100644 index 000000000..85079160c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataBuilder.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.processor.CacheableAnnotationProcessor; +import com.impetus.kundera.metadata.processor.EntityListenersProcessor; +import com.impetus.kundera.metadata.processor.IndexProcessor; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.metadata.validator.EntityValidator; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException; + +/** + * Concrete implementation of IMetadataManager. + * + * @author animesh.kumar + */ +public class MetadataBuilder +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(MetadataBuilder.class); + + /** The metadata processors. */ + private List metadataProcessors; + + /** The Validator. */ + private EntityValidator validator; + + /** persistence unit */ + private String persistenceUnit; + + /** kundera client */ + private String client; + + /** + * Instantiates a new metadata manager. + * + */ + + public MetadataBuilder(String puName, String client, Map puProperties) + { + this.persistenceUnit = puName; + this.client = client; + validator = new EntityValidatorImpl(puProperties); + metadataProcessors = new ArrayList(); + + // add processors to chain. + metadataProcessors.add(new TableProcessor(puProperties)); + metadataProcessors.add(new CacheableAnnotationProcessor()); + metadataProcessors.add(new IndexProcessor()); + metadataProcessors.add(new EntityListenersProcessor()); + } + + /** + * Validate. + * + * @param clazz + * the clazz + * + * @throws PersistenceException + * the persistence exception + */ + public final void validate(Class clazz) throws PersistenceException + { + validator.validate(clazz); + } + + /** + * Process. + * + * @param clazz + * the clazz + * @param externalProperties + * @return the entity metadata + */ + public EntityMetadata buildEntityMetadata(Class clazz) + { + + EntityMetadata metadata = new EntityMetadata(clazz); + validate(clazz); + + if (log.isDebugEnabled()) + log.debug("Processing @Entity >> " + clazz); + + for (MetadataProcessor processor : metadataProcessors) + { + // in case it is not intend for current persistence unit. + checkForRDBMS(metadata); + checkForNeo4J(metadata); + processor.process(clazz, metadata); + metadata = belongsToPersistenceUnit(metadata); + if (metadata == null) + { + break; + } + + // Check for schema attribute of Table annotation. + if (MetadataUtils.isSchemaAttributeRequired(metadata.getPersistenceUnit()) + && StringUtils.isBlank(metadata.getSchema())) + { + if (log.isErrorEnabled()) + { + log.error("It is mandatory to specify Schema alongwith Table name:" + metadata.getTableName() + + ". This entity won't be persisted"); + } + throw new InvalidEntityDefinitionException("It is mandatory to specify Schema alongwith Table name:" + + metadata.getTableName()+ ". This entity won't be persisted"); + } + } + + return metadata; + } + + private void checkForRDBMS(EntityMetadata metadata) + { + if (Constants.RDBMS_CLIENT_FACTORY.equalsIgnoreCase(client)) + { + // no more "null" as persistence unit for RDBMS scenarios! + metadata.setPersistenceUnit(persistenceUnit); + } + } + + private void checkForNeo4J(EntityMetadata metadata) + { + if (Constants.NEO4J_CLIENT_FACTORY.equalsIgnoreCase(client)) + { + // no more "null" as persistence unit for RDBMS scenarios! + metadata.setPersistenceUnit(persistenceUnit); + } + } + + /** + * If parameterised metadata is not for intended persistence unit, assign it + * to null. + * + * @param metadata + * entity metadata + * @return metadata. + */ + private EntityMetadata belongsToPersistenceUnit(EntityMetadata metadata) + { + // if pu is null and client is not rdbms OR metadata pu does not match + // with configured one. don't process for anything. + if ((metadata.getPersistenceUnit() == null && !(Constants.RDBMS_CLIENT_FACTORY.equalsIgnoreCase(client) || Constants.NEO4J_CLIENT_FACTORY + .equalsIgnoreCase(client))) + || metadata.getPersistenceUnit() != null + && !metadata.getPersistenceUnit().equals(persistenceUnit)) + { + metadata = null; + } + return metadata; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataProcessor.java new file mode 100644 index 000000000..3445b9dac --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataProcessor.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata; + +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The Interface IMetadataProcessor. + * + * @author animesh.kumar + */ +public interface MetadataProcessor +{ + + /** + * Process. + * + * @param clazz + * the clazz + * @param metadata + * the metadata + * @param puProperties + */ + void process(Class clazz, EntityMetadata metadata); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataUtils.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataUtils.java new file mode 100644 index 000000000..9a672c5fe --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/MetadataUtils.java @@ -0,0 +1,632 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.persistence.Embeddable; +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Metamodel; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.annotations.Index; +import com.impetus.kundera.index.IndexCollection; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Utility class for entity metadata related funcntionality. + * + * @author amresh.singh + */ +public class MetadataUtils +{ + + /** + * Populate column and super column maps. + * + * @param m + * the m + * @param columnNameToFieldMap + * the column name to field map + * @param superColumnNameToFieldMap + * the super column name to field map + */ + public static void populateColumnAndSuperColumnMaps(EntityMetadata m, Map columnNameToFieldMap, + Map superColumnNameToFieldMap) + { + + getEmbeddableType(m, columnNameToFieldMap, superColumnNameToFieldMap); + } + + /** + * Creates the columns field map. + * + * @param m + * the m + * @param superColumn + * the super column + * @return the map + */ + public static Map createColumnsFieldMap(EntityMetadata m, EmbeddableType superColumn) + { + Map columnNameToFieldMap = new HashMap(); + + Set attributes = superColumn.getAttributes(); + for (Attribute column : attributes) + { + columnNameToFieldMap.put(((AbstractAttribute) column).getJPAColumnName(), (Field) column.getJavaMember()); + } + return columnNameToFieldMap; + } + + /** + * Creates the super columns field map. + * + * @param m + * the m + * @return the map + */ + public static Map createSuperColumnsFieldMap(EntityMetadata m) + { + Map superColumnNameToFieldMap = new HashMap(); + getEmbeddableType(m, null, superColumnNameToFieldMap); + return superColumnNameToFieldMap; + } + + /** + * Gets the embedded collection instance. + * + * @param embeddedCollectionField + * the embedded collection field + * @return the embedded collection instance + */ + public static Collection getEmbeddedCollectionInstance(Field embeddedCollectionField) + { + Collection embeddedCollection = null; + Class embeddedCollectionFieldClass = embeddedCollectionField.getType(); + + if (embeddedCollection == null || embeddedCollection.isEmpty()) + { + if (embeddedCollectionFieldClass.equals(List.class)) + { + embeddedCollection = new ArrayList(); + } + else if (embeddedCollectionFieldClass.equals(Set.class)) + { + embeddedCollection = new HashSet(); + } + else + { + throw new InvalidEntityDefinitionException("Field " + embeddedCollectionField.getName() + + " must be either instance of List or Set"); + } + } + return embeddedCollection; + } + + /** + * Gets the embedded generic object instance. + * + * @param embeddedCollectionField + * the embedded collection field + * @return the embedded generic object instance + */ + public static Object getEmbeddedGenericObjectInstance(Field embeddedCollectionField) + { + Class embeddedClass = PropertyAccessorHelper.getGenericClass(embeddedCollectionField); + Object embeddedObject = null; + // must have a default no-argument constructor + try + { + embeddedClass.getConstructor(); + embeddedObject = embeddedClass.newInstance(); + } + catch (NoSuchMethodException nsme) + { + throw new PersistenceException(embeddedClass.getName() + + " is @Embeddable and must have a default no-argument constructor."); + } + catch (InstantiationException e) + { + throw new PersistenceException(embeddedClass.getName() + " could not be instantiated"); + } + + catch (IllegalAccessException e) + { + throw new PersistenceException(embeddedClass.getName() + " could not be accessed"); + } + return embeddedObject; + } + + /** + * Gets the embedded collection prefix. + * + * @param embeddedCollectionName + * the embedded collection name + * @return the embedded collection prefix + */ + public static String getEmbeddedCollectionPrefix(String embeddedCollectionName) + { + return embeddedCollectionName.substring(0, + embeddedCollectionName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER)); + } + + /** + * Gets the embedded collection postfix. + * + * @param embeddedCollectionName + * the embedded collection name + * @return the embedded collection postfix + */ + public static String getEmbeddedCollectionPostfix(String embeddedCollectionName) + { + return embeddedCollectionName.substring( + embeddedCollectionName.indexOf(Constants.EMBEDDED_COLUMN_NAME_DELIMITER) + 1, + embeddedCollectionName.length()); + } + + /** + * Creates a string representation of a set of foreign keys by combining + * them together separated by "~" character. + * + * Note: Assumption is that @Id will never contain "~" character. Checks for + * this are not added yet. + * + * @param foreignKeys + * the foreign keys + * @return the string + */ + public static String serializeKeys(Set foreignKeys) + { + if (null == foreignKeys || foreignKeys.isEmpty()) + { + return null; + } + + StringBuilder sb = new StringBuilder(); + for (String key : foreignKeys) + { + if (sb.length() > 0) + { + sb.append(Constants.FOREIGN_KEY_SEPARATOR); + } + sb.append(key); + } + return sb.toString(); + } + + /** + * Splits foreign keys into Set. + * + * @param foreignKeys + * the foreign keys + * @return the set + */ + public static Set deserializeKeys(String foreignKeys) + { + Set keys = new HashSet(); + + if (null == foreignKeys || foreignKeys.isEmpty()) + { + return keys; + } + + String array[] = foreignKeys.split(Constants.FOREIGN_KEY_SEPARATOR); + for (String element : array) + { + keys.add(element); + } + return keys; + } + + /** + * Sets the schema and persistence unit. + * + * @param m + * the m + * @param schemaStr + * the schema str + * @param puProperties + */ + public static void setSchemaAndPersistenceUnit(EntityMetadata m, String schemaStr, Map puProperties) + { + + if (schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) > 0) + { + String schemaName = null; + if (puProperties != null) + { + schemaName = (String) puProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + if (schemaName == null) + { + schemaName = schemaStr.substring(0, schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR)); + } + m.setSchema(schemaName); + m.setPersistenceUnit(schemaStr.substring( + schemaStr.indexOf(Constants.SCHEMA_PERSISTENCE_UNIT_SEPARATOR) + 1, schemaStr.length())); + } + else + { + m.setSchema(schemaStr); + } + } + + + /** + * Returns true, if use of secondry index is available, else false. + * + * @param persistenceUnit + * persistence unit name + * @return true, if usage is true in pu. else false. + */ + public static boolean useSecondryIndex(ClientMetadata clientMetadata) + { + return clientMetadata != null ? clientMetadata.isUseSecondryIndex() : false; + } + + + /* *//** + * Returns lucene indexing directory. + * + * @param persistenceUnit + * persistence unit name + * @return lucene directory + *//* + public static String getLuceneDirectory(String persistenceUnit) + { + if (!useSecondryIndex(persistenceUnit)) + { + ClientMetadata clientMetadata = KunderaMetadata.INSTANCE.getClientMetadata(persistenceUnit); + return clientMetadata.getLuceneIndexDir(); + } + + return null; + }*/ + + /** + * Returns mapped relational name, in case of bi directional mapping, it + * will return back pKey name of associated entity. + * + * @param relation + * holding relation. + * @return mapped/join column name. + */ + public static String getMappedName(EntityMetadata parentMetadata, Relation relation) + { + if (relation != null) + { + String joinColumn = relation.getJoinColumnName(); + if (joinColumn == null) + { + Class clazz = relation.getTargetEntity(); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(clazz); + + joinColumn = relation.getType().equals(ForeignKey.ONE_TO_MANY) ? ((AbstractAttribute) parentMetadata + .getIdAttribute()).getJPAColumnName() : ((AbstractAttribute) metadata.getIdAttribute()) + .getJPAColumnName(); + } + return joinColumn; + } + return null; + } + + /** + * Gets the enclosing document name. + * + * @param m + * the m + * @param criteria + * Input criteria + * @param viaColumnName + * true if criteria is column Name, false if + * criteria is column field name + * @return the enclosing document name + */ + public static String getEnclosingEmbeddedFieldName(EntityMetadata m, String criteria, boolean viaColumnName) + { + String enclosingEmbeddedFieldName = null; + + StringTokenizer strToken = new StringTokenizer(criteria, "."); + String embeddedFieldName = null; + String embeddableAttributeName = null; + + while (strToken.hasMoreElements()) + { + embeddableAttributeName = strToken.nextToken(); + + if (strToken.countTokens() > 0) + { + embeddedFieldName = strToken.nextToken(); + } + } + + Metamodel metaModel = KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(m.getPersistenceUnit()); + EntityType entity = metaModel.entity(m.getEntityClazz()); + + try + { + Attribute attribute = entity.getAttribute(embeddableAttributeName); + + if (((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attribute).getBindableJavaType())) + { + EmbeddableType embeddable = metaModel.embeddable(((AbstractAttribute) attribute).getBindableJavaType()); + Iterator iter = embeddable.getAttributes().iterator(); + while (iter.hasNext()) + { + AbstractAttribute attrib = (AbstractAttribute) iter.next(); + + if (viaColumnName && attrib.getName().equals(embeddedFieldName)) + { + enclosingEmbeddedFieldName = attribute.getName(); + break; + } + + if (!viaColumnName && attrib.getJPAColumnName().equals(embeddedFieldName)) + { + enclosingEmbeddedFieldName = attribute.getName(); + break; + } + } + } + + } + catch (IllegalArgumentException iax) + { + return null; + } + // + // if (!m.getColumnFieldNames().contains(criteria)) + // { + // for (EmbeddedColumn embeddedColumn : m.getEmbeddedColumnsAsList()) + // { + // List columns = embeddedColumn.getColumns(); + // for (Column column : columns) + // { + // if (viaColumnName && column.getName().equals(criteria)) + // { + // enclosingEmbeddedFieldName = embeddedColumn.getName(); + // break; + // } + // + // if (!viaColumnName && column.getField().getName().equals(criteria)) + // { + // enclosingEmbeddedFieldName = embeddedColumn.getName(); + // break; + // } + // } + // } + // + // } + return enclosingEmbeddedFieldName; + } + + /* + * public static String getEnclosingEmbeddedFieldName(EntityMetadata m, + * String columnName) { String enclosingEmbeddedFieldName = null; if + * (!m.getColumnFieldNames().contains(columnName)) { for (EmbeddedColumn + * embeddedColumn : m.getEmbeddedColumnsAsList()) { List columns = + * embeddedColumn.getColumns(); for (Column column : columns) { if + * (column.getName().equals(columnName)) { enclosingEmbeddedFieldName = + * embeddedColumn.getName(); break; } } } + * + * } return enclosingEmbeddedFieldName; } + */ + + private static void getEmbeddableType(EntityMetadata m, Map columnNameToFieldMap, + Map superColumnNameToFieldMap) + { + Metamodel metaModel = KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel(m.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + Set attributes = entityType.getAttributes(); + Iterator iter = attributes.iterator(); + while (iter.hasNext()) + { + Attribute attribute = iter.next(); + if (((MetamodelImpl) metaModel).isEmbeddable(((AbstractAttribute) attribute).getBindableJavaType())) + { + superColumnNameToFieldMap.put(((AbstractAttribute) attribute).getJPAColumnName(), + (Field) attribute.getJavaMember()); + if (columnNameToFieldMap != null) + { + getAttributeOfEmbedddable(columnNameToFieldMap, metaModel, attribute); + } + + } + else + { + if(columnNameToFieldMap != null) + { + columnNameToFieldMap.put(((AbstractAttribute) attribute).getJPAColumnName(), + (Field) attribute.getJavaMember()); + } + } + } + } + + private static void getAttributeOfEmbedddable(Map columnNameToFieldMap, Metamodel metaModel, + Attribute attribute) + { + EmbeddableType embeddable = metaModel.embeddable(((AbstractAttribute) attribute).getBindableJavaType()); + + Iterator embeddableIter = embeddable.getAttributes().iterator(); + while (embeddableIter.hasNext()) + { + Attribute embedAttrib = embeddableIter.next(); + + // Reason is to avoid in case embeddable attribute within + // embeddable. + if (!((MetamodelImpl) metaModel).isEmbeddable(embedAttrib.getJavaType())) + { + columnNameToFieldMap.put(((AbstractAttribute) embedAttrib).getJPAColumnName(), + (Field) embedAttrib.getJavaMember()); + } + else + { + getAttributeOfEmbedddable(columnNameToFieldMap, metaModel, embedAttrib); + } + } + } + + public static boolean isEmbeddedAtributeIndexable(Field embeddedField) + { + Class embeddableClass = PropertyAccessorHelper.getGenericClass(embeddedField); + Index indexAnn = embeddableClass.getAnnotation(Index.class); + IndexCollection indexCollection = embeddableClass.getAnnotation(IndexCollection.class); + if (indexCollection != null && indexCollection.columns() != null) + { + return true; + } + else if (indexAnn != null) + { + if (indexAnn.index()) + { + return true; + } + } + return false; + } + + public static boolean isColumnInEmbeddableIndexable(Field embeddedField, String columnFieldName) + { + Class embeddableClass = PropertyAccessorHelper.getGenericClass(embeddedField); + Index indexAnn = embeddableClass.getAnnotation(Index.class); + IndexCollection indexCollection = embeddableClass.getAnnotation(IndexCollection.class); + if (indexCollection != null && indexCollection.columns() != null) + { + for (com.impetus.kundera.index.Index column : indexCollection.columns()) + { + if (columnFieldName != null && column != null && column.name() != null + && column.name().equals(columnFieldName)) + { + return true; + } + } + } + else if (indexAnn != null && indexAnn.index()) + { + String[] columnsToBeIndexed = indexAnn.columns(); + if (columnFieldName != null && Arrays.asList(columnsToBeIndexed).contains(columnFieldName)) + { + return true; + } + } + return false; + } + + /** + * If client specific to parameterized persistence unit does not support + * transaction, return true else will return false. + * + * @param persistenceUnit + * @return + */ + public static boolean defaultTransactionSupported(final String persistenceUnit) + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + + String txResource = puMetadata.getProperty(PersistenceProperties.KUNDERA_TRANSACTION_RESOURCE); + + if (txResource == null) + { + return true; + } + else if (txResource.isEmpty()) + { + throw new IllegalArgumentException("Property " + PersistenceProperties.KUNDERA_TRANSACTION_RESOURCE + + " is blank"); + } + else + { + return false; + } + } + + public static boolean isSchemaAttributeRequired(final String persistenceUnit) + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + String clientFactoryName = puMetadata != null ? puMetadata + .getProperty(PersistenceProperties.KUNDERA_CLIENT_FACTORY) : null; + return !(Constants.NEO4J_CLIENT_FACTORY.equalsIgnoreCase(clientFactoryName) || Constants.RDBMS_CLIENT_FACTORY + .equalsIgnoreCase(clientFactoryName)); + } + + /** + * Checks whether a given field is Element collection field of BASIC type + * @param collectionField + * @return + */ + public static boolean isBasicElementCollectionField(Field collectionField) + { + List> genericClasses = PropertyAccessorHelper.getGenericClasses(collectionField); + for(Class genericClass : genericClasses) + { + if(genericClass.getAnnotation(Embeddable.class) != null) + { + return false; + } + } + return true; + } + + /** + * Checks whether an entity with given metadata contains a collection field + * @param m + * @return + */ + public static boolean containsBasicElementCollectionField(EntityMetadata m) + { + Metamodel metaModel = KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + Iterator iter = entityType.getAttributes().iterator(); + while (iter.hasNext()) + { + Attribute attr = iter.next(); + + if (attr.isCollection() && ! attr.isAssociation() && isBasicElementCollectionField((Field) attr.getJavaMember())) + { + return true; + } + } + return false; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationLoaderException.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationLoaderException.java new file mode 100644 index 000000000..b6d1b293e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationLoaderException.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +/** + * Runtime exception handler class ApplicationLoader. + * + * @author vivek.mishra + * + */ +public class ApplicationLoaderException extends RuntimeException +{ + + /** + * Generated Serial version UID. + */ + private static final long serialVersionUID = 2139307646040466455L; + + /** + * Default constructor using fields. + * + * @param errMsg + * error message. + */ + public ApplicationLoaderException(String errMsg) + { + super(errMsg); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationMetadata.java new file mode 100644 index 000000000..2f187ed4a --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ApplicationMetadata.java @@ -0,0 +1,408 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.persistence.metamodel.Metamodel; +import javax.persistence.spi.PersistenceUnitTransactionType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.processor.MetaModelBuilder; + +/** + * Application metadata refers to metdata specific to application(e.g. metamodel + * collection, persistence unit metdatas) Any reference which is out of + * persistence unit metadata and entity specific metadata is held by this class. + * + * @author amresh.singh + */ +public class ApplicationMetadata +{ + /** Map of Entity Metadata. */ + private Map metamodelMap = new ConcurrentHashMap(); + + /** Map of Persistence Unit Metadata. */ + private Map persistenceUnitMetadataMap = new ConcurrentHashMap(); + + /** The Constant log. */ + private static Logger logger = LoggerFactory.getLogger(ApplicationMetadata.class); + + // private MetaModelBuilder metaModelBuilder = new MetaModelBuilder(); + + private Map metaModelBuilder = new ConcurrentHashMap(); + + /** + * Collection instance to hold clazz's full name to persistence unit + * mapping. Valid Assumption: 1 class can belong to 1 pu only. Reason is @table + * needs to give pu name! + */ + private Map> clazzToPuMap; + + private Map namedNativeQueries; + + /** + * Adds the entity metadata. + * + * @param persistenceUnit + * the persistence unit + * @param clazz + * the clazz + * @param entityMetadata + * the entity metadata + */ + public void addEntityMetadata(String persistenceUnit, Class clazz, EntityMetadata entityMetadata) + { + Metamodel metamodel = getMetamodelMap().get(persistenceUnit); + Map entityClassToMetadataMap = ((MetamodelImpl) metamodel).getEntityMetadataMap(); + if (entityClassToMetadataMap == null || entityClassToMetadataMap.isEmpty()) + { + entityClassToMetadataMap.put(clazz.getName(), entityMetadata); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("Entity meta model already exists for persistence unit " + persistenceUnit + " and class " + + clazz + ". Noting needs to be done"); + } + } + + /** + * Adds the persistence unit metadata. + * + * @param persistenceUnit + * the persistence unit + * @param persistenceUnitMetadata + * the persistence unit metadata + */ + public void addPersistenceUnitMetadata(Map metadata) + { + getPersistenceUnitMetadataMap().putAll(metadata); + } + + /** + * Gets the metamodel map. + * + * @return the entityMetadataMap + */ + public Map getMetamodelMap() + { + if (metamodelMap == null) + { + metamodelMap = new HashMap(); + } + return metamodelMap; + } + + /** + * Gets the persistence unit metadata. + * + * @param persistenceUnit + * the persistence unit + * @return the persistence unit metadata + */ + public PersistenceUnitMetadata getPersistenceUnitMetadata(String persistenceUnit) + { + return getPersistenceUnitMetadataMap().get(persistenceUnit); + } + + /** + * Gets the metamodel. + * + * @param persistenceUnit + * the persistence unit + * @return the metamodel + */ + public Metamodel getMetamodel(String persistenceUnit) + { + Map model = getMetamodelMap(); + return persistenceUnit != null && model.containsKey(persistenceUnit) ? model.get(persistenceUnit) : null; + } + + /** + * Gets the persistence unit metadata map. + * + * @return the persistenceUnitMetadataMap + */ + public Map getPersistenceUnitMetadataMap() + { + return persistenceUnitMetadataMap; + } + + /** + * Sets the clazz to pu map. + * + * @param map + * the map + */ + public void setClazzToPuMap(Map> map) + { + if (clazzToPuMap == null) + { + this.clazzToPuMap = map; + } + else + { + clazzToPuMap.putAll(map); + } + } + + /** + * Gets the mapped persistence unit. + * + * @param clazz + * the clazz + * + * @return the mapped persistence unit + */ + public List getMappedPersistenceUnit(Class clazz) + { + return this.clazzToPuMap != null ? this.clazzToPuMap.get(clazz.getName()) : null; + } + + /** + * returns mapped persistence unit. + * + * @param clazzName + * clazz name. + * + * @return mapped persistence unit. + */ + public String getMappedPersistenceUnit(String clazzName) + { + + List pus = clazzToPuMap.get(clazzName); + + final int _first = 0; + String pu = null; + + if (pus != null && !pus.isEmpty()) + { + if (pus.size() == 2) + { + onError(clazzName); + } + return pus.get(_first); + } + else + { + Set mappedClasses = this.clazzToPuMap.keySet(); + boolean found = false; + for (String clazz : mappedClasses) + { + if (found && clazz.endsWith("." + clazzName)) + { + onError(clazzName); + } + else if (clazz.endsWith("." + clazzName)) + { + pu = clazzToPuMap.get(clazz).get(_first); + found = true; + } + } + } + + return pu; + } + + /** + * Adds parameterised query with given name into collection. Throws + * exception if duplicate name is provided. + * + * @param queryName + * query name. + * @param query + * named/native query. + * @param isNativeQuery + * true, if it is a namednativequery. + * + */ + public void addQueryToCollection(String queryName, String query, boolean isNativeQuery, Class clazz) + { + if (namedNativeQueries == null) + { + namedNativeQueries = new HashMap(); + } + if (!namedNativeQueries.containsKey(queryName)) + { + namedNativeQueries.put(queryName, new QueryWrapper(queryName, query, isNativeQuery, clazz)); + } + // No null check made as it will never hold null value + else if (!getQuery(queryName).equals(query)) + { + logger.error("Duplicate named/native query with name:" + queryName + + "found! Already there is a query with same name:" + namedNativeQueries.get(queryName)); + throw new ApplicationLoaderException("Duplicate named/native query with name:" + queryName + + "found! Already there is a query with same name:" + namedNativeQueries.get(queryName)); + } + } + + /** + * Returns query interface. + * + * @param name + * query name. + * @return query. + */ + public String getQuery(String name) + { + QueryWrapper wrapper = namedNativeQueries != null ? namedNativeQueries.get(name) : null; + return wrapper != null ? wrapper.getQuery() : null; + } + + /** + * Returns true, if query is named native or native, else false + * + * @param name + * mapped name. + * @return boolean value + */ + public boolean isNative(String name) + { + QueryWrapper wrapper = namedNativeQueries != null ? namedNativeQueries.get(name) : null; + return wrapper != null ? wrapper.isNativeQuery() : false; + } + + public Class getMappedClass(String name) + { + QueryWrapper wrapper = namedNativeQueries != null ? namedNativeQueries.get(name) : null; + return wrapper != null ? wrapper.getMappedClazz() : null; + } + + /** + * Handler error and log statements. + * + * @param clazzName + * class name. + */ + private void onError(String clazzName) + { + logger.error("Duplicate name:" + clazzName + "Please provide entity with complete package name."); + throw new ApplicationLoaderException("Duplicate name:" + clazzName + + "Please provide entity with complete package name"); + } + + private class QueryWrapper + { + private String queryName; + + private String query; + + private boolean isNativeQuery; + + private Class entityClazz; + + /** + * @param queryName + * @param query + * @param isNativeQuery + */ + public QueryWrapper(String queryName, String query, boolean isNativeQuery, Class clazz) + { + this.queryName = queryName; + this.query = query; + this.isNativeQuery = isNativeQuery; + this.entityClazz = clazz; + } + + /** + * @return the query + */ + String getQuery() + { + return query; + } + + /** + * @return the isNativeQuery + */ + boolean isNativeQuery() + { + return isNativeQuery; + } + + Class getMappedClazz() + { + return entityClazz; + } + } + + /** + * @return the metaModelBuilder + */ + public MetaModelBuilder getMetaModelBuilder(String persistenceUnit) + { + if (metaModelBuilder.containsKey(persistenceUnit)) + { + return metaModelBuilder.get(persistenceUnit); + } + else + { + MetaModelBuilder builder = new MetaModelBuilder(); + metaModelBuilder.put(persistenceUnit, builder); + return builder; + } + } + + /** + * + */ + void unloadApplicationMatadata(final String pu) + { + Metamodel metamodel = getMetamodel(pu); + if (metamodel != null) + { + this.metamodelMap.remove(pu); + ((MetamodelImpl) metamodel).setEntityMetadataMap(null); + ((MetamodelImpl) metamodel).setEntityNameToClassMap(null); + ((MetamodelImpl) metamodel).addKeyValues(new HashMap()); + } + MetaModelBuilder builder = getMetaModelBuilder(pu); + if (builder != null) + { + this.metaModelBuilder.remove(pu); + builder = null; + } + + // for (String className : clazzToPuMap.keySet()) + // { + // List pus = clazzToPuMap.get(className); + // } + // this.clazzToPuMap = null; + + PersistenceUnitMetadata puMetadata = getPersistenceUnitMetadata(pu); + if (puMetadata != null) + { + this.persistenceUnitMetadataMap.remove(pu); + puMetadata.setClasses(new ArrayList()); + puMetadata.setExcludeUnlistedClasses(false); + puMetadata.setPackages(new ArrayList()); + puMetadata.setPersistenceUnitName(null); + puMetadata.setProperties(new Properties()); + puMetadata.setTransactionType(PersistenceUnitTransactionType.RESOURCE_LOCAL); + puMetadata.setProvider(null); + puMetadata = null; + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ClientMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ClientMetadata.java new file mode 100644 index 000000000..93a824279 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/ClientMetadata.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import org.apache.commons.lang.StringUtils; + +/** + * The Class ClientMetadata. + * + * @author amresh.singh + */ +public class ClientMetadata +{ + + /** The client implementor. */ + private String clientImplementor; + + /** The index implementor. */ + private String indexImplementor; + + /** The Lucene index dir. */ + private String LuceneIndexDir; + + /** + * Gets the client implementor. + * + * @return the clientImplementor + */ + public String getClientImplementor() + { + return clientImplementor; + } + + /** + * Sets the client implementor. + * + * @param clientImplementor + * the clientImplementor to set + */ + public void setClientImplementor(String clientImplementor) + { + this.clientImplementor = clientImplementor; + } + + /** + * Gets the index implementor. + * + * @return the indexImplementor + */ + public String getIndexImplementor() + { + return indexImplementor; + } + + /** + * Sets the index implementor. + * + * @param indexImplementor + * the indexImplementor to set + */ + public void setIndexImplementor(String indexImplementor) + { + this.indexImplementor = indexImplementor; + } + + /** + * Checks if is use secondry index. + * + * @return the useSecondryIndex + */ + public boolean isUseSecondryIndex() + { + // if lucene directory and indexer class both not present then return + // true. + + return StringUtils.isEmpty(LuceneIndexDir) && StringUtils.isBlank(LuceneIndexDir) + && StringUtils.isEmpty(indexImplementor) && StringUtils.isBlank(indexImplementor); + } + + /** + * Gets the lucene index dir. + * + * @return the luceneIndexDir + */ + public String getLuceneIndexDir() + { + return LuceneIndexDir; + } + + /** + * Sets the lucene index dir. + * + * @param luceneIndexDir + * the luceneIndexDir to set + */ + public void setLuceneIndexDir(String luceneIndexDir) + { + LuceneIndexDir = luceneIndexDir; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Column.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Column.java new file mode 100644 index 000000000..3cf24303e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Column.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; + +/** + * Holds metadata for entity column. + * + * @author animesh.kumar + */ +public final class Column +{ + + /** name of the column. */ + private String name; + + /** column field. */ + private Field field; + + /** whether indexable. */ + private boolean isIndexable; // default is NOT indexable + + /** + * Instantiates a new column. + * + * @param name + * the name + * @param field + * the field + */ + public Column(String name, Field field) + { + this.name = name; + this.field = field; + } + + public Column(String name, Field field, boolean isIndexable) + { + this.name = name; + this.field = field; + this.isIndexable = isIndexable; + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() + { + return name; + } + + /** + * Gets the field. + * + * @return the field + */ + public Field getField() + { + return field; + } + + /** + * Checks if is indexable. + * + * @return the isIndexable + */ + public boolean isIndexable() + { + return isIndexable; + } + + /** + * Sets the indexable. + * + * @param isIndexable + * the isIndexable to set + */ + public void setIndexable(boolean isIndexable) + { + this.isIndexable = isIndexable; + } + +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/CoreMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/CoreMetadata.java new file mode 100644 index 000000000..fc3e4ab92 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/CoreMetadata.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import com.impetus.kundera.proxy.LazyInitializerFactory; + +/** + * The Class CoreMetadata. + * + * @author amresh.singh + */ +public class CoreMetadata +{ + + /** The lazy initializer factory. */ + private LazyInitializerFactory lazyInitializerFactory; + + /** + * Gets the lazy initializer factory. + * + * @return the lazy initializer factory + */ + public LazyInitializerFactory getLazyInitializerFactory() + { + return lazyInitializerFactory; + } + + /** + * Sets the lazy initializer factory. + * + * @param lazyInitializerFactory + * the new lazy initializer factory + */ + public void setLazyInitializerFactory(LazyInitializerFactory lazyInitializerFactory) + { + this.lazyInitializerFactory = lazyInitializerFactory; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EmbeddedColumn.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EmbeddedColumn.java new file mode 100644 index 000000000..288b46325 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EmbeddedColumn.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +/** + * Holds metadata for embedded column in entity. + * + * @author animesh.kumar + */ +public final class EmbeddedColumn +{ + + /** The name. */ + private String name; + + /** Super column field. */ + private Field field; + + /** The columns. */ + private List columns; + + /** + * Instantiates a new super column. + * + * @param name + * the name + * @param f + * the f + */ + public EmbeddedColumn(String name, Field f) + { + this.name = name; + this.field = f; + columns = new ArrayList(); + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() + { + return name; + } + + /** + * Sets the name. + * + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * Gets the field. + * + * @return the field + */ + public Field getField() + { + return field; + } + + /** + * Sets the field. + * + * @param field + * the field to set + */ + public void setField(Field field) + { + this.field = field; + } + + /** + * Gets the columns. + * + * @return the columns + */ + public List getColumns() + { + return columns; + } + + /** + * Adds the column. + * + * @param name + * the name + * @param field + * the field + */ + public void addColumn(String name, Field field) + { + columns.add(new Column(name, field)); + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EntityMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EntityMetadata.java new file mode 100644 index 000000000..de00f983e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/EntityMetadata.java @@ -0,0 +1,752 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.JoinColumn; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.metamodel.SingularAttribute; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.persistence.event.CallbackMethod; + +/** + * Holds metadata for entities. + * + * @author animesh.kumar + */ + +public final class EntityMetadata +{ + + /* + * Entity related metadata properties + */ + + /** class corresponding to this meta. */ + Class entityClazz; + + /** Name of Persistence Object. */ + private String tableName; + + /** database name. */ + private String schema; + + /** Persistence unit of database this entity is to be persisted. */ + private String persistenceUnit; + + /** The index name. */ + private String indexName; + + /** The is indexable. */ + private boolean isIndexable = true; // default is indexable + + /** Cacheable?. */ + private boolean cacheable = false; // default is to not set second-level + + private boolean isCounterColumnType = false; + + private SingularAttribute idAttribute; + + // private List colToBeIndexed; + // private List colToBeIndexed; + // private Map + // colToBeIndexed; + + private Map jpaColumnMapping = new HashMap(); + + /** The read identifier method. */ + private Method readIdentifierMethod; + + /** The write identifier method. */ + private Method writeIdentifierMethod; + + /** The index prperties. */ + // private List indexPrperties = new + // ArrayList(); + + private Map indexPrperties = new HashMap(); + + // entity listeners map + // key=>ListenerAnnotations, like @PrePersist, @PreUpdate etc.; + // value=>EntityLisntener Class and method + /** The callback methods map. */ + private Map, List> callbackMethodsMap = new HashMap, List>(); + + /** Relationship map, key=>property name, value=>relation. */ + private Map relationsMap = new HashMap(); + + /** type. */ + private Type type; + + /** The is relation via join table. */ + private boolean isRelationViaJoinTable; + + private List relationNames; + + // Whether it contains One-To-Many relationship + private boolean isParent; + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(EntityMetadata.class); + + /** + * The Enum Type. + */ + public static enum Type + { + + /** Denotes that the Entity is related to a ColumnFamily. */ + COLUMN_FAMILY + { + + public boolean isColumnFamilyMetadata() + { + return true; + } + + public boolean isSuperColumnFamilyMetadata() + { + return false; + } + + public boolean isDocumentMetadata() + { + return false; + } + + }, + + /** Denotes that the Entity is related to a SuperColumnFamily. */ + SUPER_COLUMN_FAMILY + { + + public boolean isColumnFamilyMetadata() + { + return false; + } + + public boolean isSuperColumnFamilyMetadata() + { + return true; + } + + public boolean isDocumentMetadata() + { + return false; + } + + }; + + /** + * Checks if is column family metadata. + * + * @return true, if is column family metadata + */ + public abstract boolean isColumnFamilyMetadata(); + + /** + * Checks if is super column family metadata. + * + * @return true, if is super column family metadata + */ + public abstract boolean isSuperColumnFamilyMetadata(); + + /** + * Checks if is Document metadata. + * + * @return true, if is Document metadata + */ + public abstract boolean isDocumentMetadata(); + } + + /** + * Gets the type. + * + * @return the type + */ + public Type getType() + { + return type; + } + + /** + * Sets the type. + * + * @param type + * the new type + */ + public void setType(Type type) + { + this.type = type; + } + + /** + * Instantiates a new metadata. + * + * @param entityClazz + * the entity clazz + */ + public EntityMetadata(Class entityClazz) + { + this.entityClazz = entityClazz; + + } + + /** + * Gets the entity clazz. + * + * @return the entity clazz + */ + public Class getEntityClazz() + { + return entityClazz; + } + + /** + * Gets the table name. + * + * @return the tableName + */ + public String getTableName() + { + return tableName; + } + + /** + * Sets the table name. + * + * @param tableName + * the tableName to set + */ + public void setTableName(String tableName) + { + this.tableName = tableName; + } + + /** + * Gets the schema. + * + * @return the schema + */ + public String getSchema() + { + return schema; + } + + /** + * Sets the schema. + * + * @param schema + * the schema to set + */ + public void setSchema(String schema) + { + this.schema = schema; + } + + /** + * Gets the persistence unit. + * + * @return the persistenceUnit + */ + public String getPersistenceUnit() + { + return persistenceUnit; + } + + /** + * Sets the persistence unit. + * + * @param persistenceUnit + * the persistenceUnit to set + */ + public void setPersistenceUnit(String persistenceUnit) + { + this.persistenceUnit = persistenceUnit; + } + + /** + * Gets the read identifier method. + * + * @return the readIdentifierMethod + */ + public Method getReadIdentifierMethod() + { + return readIdentifierMethod; + } + + /** + * Sets the read identifier method. + * + * @param readIdentifierMethod + * the readIdentifierMethod to set + */ + public void setReadIdentifierMethod(Method readIdentifierMethod) + { + this.readIdentifierMethod = readIdentifierMethod; + } + + /** + * Gets the write identifier method. + * + * @return the writeIdentifierMethod + */ + public Method getWriteIdentifierMethod() + { + return writeIdentifierMethod; + } + + /** + * Sets the write identifier method. + * + * @param writeIdentifierMethod + * the writeIdentifierMethod to set + */ + public void setWriteIdentifierMethod(Method writeIdentifierMethod) + { + this.writeIdentifierMethod = writeIdentifierMethod; + } + + /** + * Adds the index property. + * + * @param index + * the index + */ + public void addIndexProperty(PropertyIndex index) + { + indexPrperties.put(index.getName(), index); + } + + /** + * Adds the relation. + * + * @param property + * the property + * @param relation + * the relation + */ + public void addRelation(String property, Relation relation) + { + relationsMap.put(property, relation); + addRelationName(relation); + } + + /** + * Gets the relation. + * + * @param property + * the property + * @return the relation + */ + public Relation getRelation(String property) + { + return relationsMap.get(property); + } + + /** + * Gets the relations. + * + * @return the relations + */ + public List getRelations() + { + return new ArrayList(relationsMap.values()); + } + + /** + * Gets the index properties. + * + * @return the index properties + */ + public Map getIndexProperties() + { + return indexPrperties; + } + + /** + * Gets the index name. + * + * @return the index name + */ + public String getIndexName() + { + return indexName; + } + + /** + * Sets the index name. + * + * @param indexName + * the new index name + */ + public void setIndexName(String indexName) + { + this.indexName = indexName; + } + + /** + * Checks if is indexable. + * + * @return true, if is indexable + */ + public boolean isIndexable() + { + return isIndexable; + } + + /** + * Sets the indexable. + * + * @param isIndexable + * the new indexable + */ + public void setIndexable(boolean isIndexable) + { + this.isIndexable = isIndexable; + } + + /** + * Sets the callback methods map. + * + * @param callbackMethodsMap + * the callback methods map + */ + public void setCallbackMethodsMap(Map, List> callbackMethodsMap) + { + this.callbackMethodsMap = callbackMethodsMap; + } + + /** + * Gets the callback methods map. + * + * @return the callback methods map + */ + public Map, List> getCallbackMethodsMap() + { + return callbackMethodsMap; + } + + /** + * Gets the callback methods. + * + * @param event + * the event + * + * @return the callback methods + */ + public List getCallbackMethods(Class event) + { + return this.callbackMethodsMap.get(event); + } + + /** + * Checks if is embeddable. + * + * @param fieldClass + * the field class + * @return true, if is embeddable + */ + // public boolean isEmbeddable(Class fieldClass) + // { + // return embeddableCollection.contains(fieldClass); + // } + + /** + * Adds the to embed collection. + * + * @param fieldClass + * the field class + */ + // public void addToEmbedCollection(Class fieldClass) + // { + // if (!embeddableCollection.contains(fieldClass)) + // { + // embeddableCollection.add(fieldClass); + // } + // } + + /** + * Checks if is cacheable. + * + * @return the cacheable + */ + public boolean isCacheable() + { + return cacheable; + } + + /** + * Sets the cacheable. + * + * @param cacheable + * the cacheable to set + */ + public void setCacheable(boolean cacheable) + { + this.cacheable = cacheable; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + int start = 0; + StringBuilder builder = new StringBuilder(); + builder.append(entityClazz.getName() + " (\n"); + builder.append("\tTable: " + tableName + ", \n"); + builder.append("\tKeyspace: " + schema + ",\n"); + builder.append("\tPersistence Unit: " + persistenceUnit + ",\n"); + builder.append("\tId: " + idAttribute.getName() + ",\n"); + builder.append("\tCacheable: " + cacheable + ",\n"); + + if (!indexPrperties.isEmpty()) + { + + builder.append("\tIndexes ("); + start = 0; + for (String indexColumnName : indexPrperties.keySet()) + { + if (start++ != 0) + { + builder.append(", "); + } + builder.append(indexPrperties.get(indexColumnName)); + } + builder.append("),\n"); + } + + if (!callbackMethodsMap.isEmpty()) + { + builder.append("\tListeners (\n"); + for (Map.Entry, List> entry : callbackMethodsMap.entrySet()) + { + String key = entry.getKey().getSimpleName(); + for (CallbackMethod cbm : entry.getValue()) + { + builder.append("\t\t" + key + ": " + cbm + "\n"); + } + } + builder.append("\t)\n"); + } + + if (!relationsMap.isEmpty()) + { + builder.append("\tRelation (\n"); + for (Relation rel : relationsMap.values()) + { + if (rel.getMapKeyJoinClass() != null) + builder.append(" --- via ").append(rel.getMapKeyJoinClass().getSimpleName()).append(" ---\n"); + builder.append("\t\t" + rel.getTargetEntity().getName() + "#" + rel.getProperty().getName()); + builder.append(" (" + rel.getCascades()); + builder.append(", " + rel.getType()); + builder.append(", " + rel.fetchType); + builder.append(")\n"); + } + builder.append("\t)\n"); + } + + builder.append(")"); + return builder.toString(); + } + + /** + * Getter method for isRelatedViaJoinTable. + * + * @return true, if holds join table relation, else false. + */ + public boolean isRelationViaJoinTable() + { + return isRelationViaJoinTable; + } + + /** + * @return the isParent + */ + public boolean isParent() + { + return isParent; + } + + /** + * @param isParent + * the isParent to set + */ + public void setParent(boolean isParent) + { + this.isParent = isParent; + } + + /** + * Setter method for isRelatedViaJoinTable. + * + * @param isRelationViaJoinTable + * the new relation via join table + */ + public void setRelationViaJoinTable(boolean isRelationViaJoinTable) + { + this.isRelationViaJoinTable = isRelationViaJoinTable; + } + + public List getRelationNames() + { + return relationNames; + } + + /** + * Method to add specific relation name for given relational field. + * + * @param rField + * relation object. + */ + private void addRelationName(Relation rField) + { + if (!rField.isRelatedViaJoinTable()) + { + String relationName = getJoinColumnName(rField.getProperty()); + if (rField.getProperty().isAnnotationPresent(PrimaryKeyJoinColumn.class)) + { + relationName = this.getIdAttribute().getName(); + } + + addToRelationNameCollection(relationName); + } + } + + /** + * Adds relation name to relation name collection. + * + * @param relationName + * relational name + */ + private void addToRelationNameCollection(String relationName) + { + if (relationNames == null) + { + relationNames = new ArrayList(); + } + if (relationName != null) + { + relationNames.add(relationName); + } + } + + /** + * Gets the relation field name. + * + * @param relation + * the relation + * @return the relation field name + */ + private String getJoinColumnName(Field relation) + { + String columnName = null; + JoinColumn ann = relation.getAnnotation(JoinColumn.class); + if (ann != null) + { + columnName = ann.name(); + + } + return columnName != null ? columnName : relation.getName(); + } + + /** + * @return the isCounterColumnType + */ + public boolean isCounterColumnType() + { + return isCounterColumnType; + } + + /** + * @param isCounterColumnType + * the isCounterColumnType to set + */ + public void setCounterColumnType(boolean isCounterColumnType) + { + this.isCounterColumnType = isCounterColumnType; + } + + /** + * @return the idAttribute + */ + public SingularAttribute getIdAttribute() + { + return idAttribute; + } + + /** + * @param idAttribute + * the idAttribute to set + */ + public void setIdAttribute(SingularAttribute idAttribute) + { + this.idAttribute = idAttribute; + } + + // /** + // * @return the colToBeIndexed + // */ + // public Map + // getColToBeIndexed() + // { + // return colToBeIndexed; + // } + // + // /** + // * @param colToBeIndexed + // * the colToBeIndexed to set + // */ + // public void setColToBeIndexed(Map colToBeIndexed) + // { + // this.colToBeIndexed = colToBeIndexed; + // } + + // /** + // * Checks if is indexable. + // * + // * @return true, if is indexable + // */ + // public boolean isColumnIndexable(String columnName) + // { + // return getColToBeIndexed() != null && getColToBeIndexed().get(columnName) + // != null; + // } + + public void addJPAColumnMapping(String jpaColumnName, String fieldName) + { + jpaColumnMapping.put(jpaColumnName, fieldName); + } + + public String getFieldName(String jpaColumnName) + { + return jpaColumnMapping.get(jpaColumnName); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/IdDiscriptor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/IdDiscriptor.java new file mode 100644 index 000000000..88b4fde4c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/IdDiscriptor.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import javax.persistence.GenerationType; + +/** + * Class IdDiscriptor holds all information about generating id. + * + * @author Kuldeep.kumar + * + */ +public class IdDiscriptor +{ + private GenerationType strategy; + + private TableGeneratorDiscriptor tableDiscriptor; + + private SequenceGeneratorDiscriptor sequenceDiscriptor; + + /** + * @return the strategy + */ + public GenerationType getStrategy() + { + return strategy; + } + + /** + * @param strategy + * the strategy to set + */ + public void setStrategy(GenerationType strategy) + { + this.strategy = strategy; + } + + /** + * @return the tableDiscriptor + */ + public TableGeneratorDiscriptor getTableDiscriptor() + { + return tableDiscriptor; + } + + /** + * @param tableDiscriptor + * the tableDiscriptor to set + */ + public void setTableDiscriptor(TableGeneratorDiscriptor tableDiscriptor) + { + this.tableDiscriptor = tableDiscriptor; + } + + /** + * @return the sequenceDiscriptor + */ + public SequenceGeneratorDiscriptor getSequenceDiscriptor() + { + return sequenceDiscriptor; + } + + /** + * @param sequenceDiscriptor + * the sequenceDiscriptor to set + */ + public void setSequenceDiscriptor(SequenceGeneratorDiscriptor sequenceDiscriptor) + { + this.sequenceDiscriptor = sequenceDiscriptor; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/JoinTableMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/JoinTableMetadata.java new file mode 100644 index 000000000..13606d063 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/JoinTableMetadata.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; + +/** + * The Class JoinTableMetadata. + * + * @author Amresh Singh + */ +public class JoinTableMetadata +{ + + /** The join table name. */ + private String joinTableName; + + /** The join table schema. */ + private String joinTableSchema; + + /** The join columns. */ + private Set joinColumns; + + /** The inverse join columns. */ + private Set inverseJoinColumns; + + /** + * Instantiates a new join table metadata. + * + * @param relationField + * the relation field + */ + public JoinTableMetadata(Field relationField) + { + JoinTable jtAnn = relationField.getAnnotation(JoinTable.class); + + setJoinTableName(jtAnn.name()); + setJoinTableSchema(jtAnn.schema()); + + for (JoinColumn joinColumn : jtAnn.joinColumns()) + { + addJoinColumns(joinColumn.name()); + } + + for (JoinColumn inverseJoinColumn : jtAnn.inverseJoinColumns()) + { + addInverseJoinColumns(inverseJoinColumn.name()); + } + } + + /** + * Gets the join table name. + * + * @return the joinTableName + */ + public String getJoinTableName() + { + return joinTableName; + } + + /** + * Sets the join table name. + * + * @param joinTableName + * the joinTableName to set + */ + public void setJoinTableName(String joinTableName) + { + this.joinTableName = joinTableName; + } + + /** + * Gets the join table schema. + * + * @return the joinTableSchema + */ + public String getJoinTableSchema() + { + return joinTableSchema; + } + + /** + * Sets the join table schema. + * + * @param joinTableSchema + * the joinTableSchema to set + */ + public void setJoinTableSchema(String joinTableSchema) + { + this.joinTableSchema = joinTableSchema; + } + + /** + * Gets the join columns. + * + * @return the joinColumns + */ + public Set getJoinColumns() + { + return joinColumns; + } + + /** + * Adds the join columns. + * + * @param joinColumn + * the joinColumns to add + */ + public void addJoinColumns(String joinColumn) + { + if (joinColumns == null || joinColumns.isEmpty()) + { + joinColumns = new HashSet(); + } + joinColumns.add(joinColumn); + } + + /** + * Gets the inverse join columns. + * + * @return the inverseJoinColumns + */ + public Set getInverseJoinColumns() + { + return inverseJoinColumns; + } + + /** + * Adds the inverse join columns. + * + * @param inverseJoinColumn + * the inverseJoinColumns to add + */ + public void addInverseJoinColumns(String inverseJoinColumn) + { + if (inverseJoinColumns == null || inverseJoinColumns.isEmpty()) + { + inverseJoinColumns = new HashSet(); + } + + inverseJoinColumns.add(inverseJoinColumn); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/KunderaMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/KunderaMetadata.java new file mode 100644 index 000000000..1cb04773f --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/KunderaMetadata.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + + +/** + * The Class KunderaMetadata. + * + * @author amresh.singh + */ +public class KunderaMetadata +{ + /* Metadata for Kundera core */ + /** The core metadata. */ + private CoreMetadata coreMetadata; + + /* User application specific metadata */ + /** The application metadata. */ + private ApplicationMetadata applicationMetadata; + + + /** The Constant INSTANCE. */ + public static final KunderaMetadata INSTANCE = new KunderaMetadata(); + + /** + * Instantiates a new kundera metadata. + */ + private KunderaMetadata() + { + + } + + /* + * public static synchronized KunderaMetadata getInstance() { if (instance + * == null) { instance = new KunderaMetadata(); } return instance; } + */ + /** + * Gets the application metadata. + * + * @return the applicationMetadata + */ + public ApplicationMetadata getApplicationMetadata() + { + if (applicationMetadata == null) + { + applicationMetadata = new ApplicationMetadata(); + } + return applicationMetadata; + } + + /** + * Gets the core metadata. + * + * @return the coreMetadata + */ + public CoreMetadata getCoreMetadata() + { + return coreMetadata; + } + + /** + * Sets the application metadata. + * + * @param applicationMetadata + * the applicationMetadata to set + */ + public void setApplicationMetadata(ApplicationMetadata applicationMetadata) + { + this.applicationMetadata = applicationMetadata; + } + + /** + * Sets the core metadata. + * + * @param coreMetadata + * the coreMetadata to set + */ + public void setCoreMetadata(CoreMetadata coreMetadata) + { + this.coreMetadata = coreMetadata; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/MetamodelImpl.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/MetamodelImpl.java new file mode 100644 index 000000000..1579c4b96 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/MetamodelImpl.java @@ -0,0 +1,429 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.metamodel.StaticMetamodel; +import javax.persistence.metamodel.Type.PersistenceType; + +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; + +/** + * The Class MetamodelImpl implements MetaModel interface. + * Responsible for holding reference to complete metamodel and relative + * information, in the form of: a) EntityTypes b) Embeddables + * c)MappedSuperClassTypes + * + * @author vivek.mishra + */ +@StaticMetamodel(value = MetamodelImpl.class) +public class MetamodelImpl implements Metamodel +{ + /** The entity metadata map. */ + Map entityMetadataMap; + + /** The entity name to class map. */ + Map> entityNameToClassMap; + + /** The managed types. */ + private Map, EntityType> entityTypes; + + /** The embeddables. */ + private Map, ManagedType> embeddables; + + /** The mapped super class types. */ + private Map, ManagedType> mappedSuperClassTypes; + + private Map keyValues; + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#entity(java.lang.Class) + */ + @Override + public EntityType entity(Class paramClass) + { + EntityType entityType = entityTypes.get(paramClass); + if (entityType == null) + { + throw new IllegalArgumentException("Not an entity, {class:" + paramClass + "}"); + } + return entityType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#managedType(java.lang.Class) + */ + @Override + public ManagedType managedType(Class paramClass) + { + ManagedType managedType = entityTypes.get(paramClass); + if (managedType == null) + { + managedType = embeddables.get(paramClass); + if (managedType == null) + { + managedType = mappedSuperClassTypes.get(paramClass); + } + } + + if (managedType == null) + { + throw new IllegalArgumentException("Not a managed type, {class: " + paramClass + "}"); + } + return managedType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#embeddable(java.lang.Class) + */ + @Override + public EmbeddableType embeddable(Class paramClass) + { + EmbeddableType embeddableType = (EmbeddableType) embeddables.get(paramClass); + if (embeddableType == null) + { + throw new IllegalArgumentException("Not a embeddable type, {class: " + paramClass + "}"); + } + + return embeddableType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#getManagedTypes() + */ + @Override + public Set> getManagedTypes() + { + Set> managedTypeCollection = new HashSet>(); + if (entityTypes != null) + { + managedTypeCollection.addAll(entityTypes.values()); + } + if (embeddables != null) + { + managedTypeCollection.addAll((Collection>) embeddables.values()); + } + if (mappedSuperClassTypes != null) + { + managedTypeCollection.addAll((Collection>) mappedSuperClassTypes.values()); + } + return managedTypeCollection; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#getEntities() + */ + @Override + public Set> getEntities() + { + Set> entities = null; + if (entityTypes != null) + { + entities = new HashSet>(entityTypes.values()); + } + return entities; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Metamodel#getEmbeddables() + */ + @Override + public Set> getEmbeddables() + { + Set embeddableEntities = null; + if (embeddables != null) + { + embeddableEntities = new HashSet(embeddables.values()); + } + return embeddableEntities; + } + + /** + * Instantiates a new metamodel impl. + */ + public MetamodelImpl() + { + super(); + setEntityMetadataMap(new HashMap()); + } + + /** + * Gets the entity metadata map. + * + * @return the entityMetadataMap + */ + public Map getEntityMetadataMap() + { + if (entityMetadataMap == null) + { + entityMetadataMap = new HashMap(); + } + return entityMetadataMap; + } + + /** + * Sets the entity metadata map. + * + * @param entityMetadataMap + * the entityMetadataMap to set + */ + public void setEntityMetadataMap(Map entityMetadataMap) + { + this.entityMetadataMap = entityMetadataMap; + } + + /** + * Adds the entity metadata. + * + * @param clazz + * the clazz + * @param entityMetadata + * the entity metadata + */ + public void addEntityMetadata(Class clazz, EntityMetadata entityMetadata) + { + getEntityMetadataMap().put(clazz.getName(), entityMetadata); + } + + /** + * Gets the entity metadata. + * + * @param entityClass + * the entity class + * @return the entity metadata + */ + public EntityMetadata getEntityMetadata(Class entityClass) + { + return getEntityMetadataMap().get(entityClass.getName()); + } + + /** + * Gets the entity name to class map. + * + * @return the entityNameToClassMap + */ + public Map> getEntityNameToClassMap() + { + if (entityNameToClassMap == null) + { + entityNameToClassMap = new HashMap>(); + } + return entityNameToClassMap; + } + + /** + * Sets the entity name to class map. + * + * @param entityNameToClassMap + * the entityNameToClassMap to set + */ + public void setEntityNameToClassMap(Map> entityNameToClassMap) + { + this.entityNameToClassMap = entityNameToClassMap; + } + + /** + * Adds the entity name to class mapping. + * + * @param className + * the class name + * @param entityClass + * the entity class + */ + public void addEntityNameToClassMapping(String className, Class entityClass) + { + getEntityNameToClassMap().put(className, entityClass); + } + + /** + * Gets the entity class. + * + * @param className + * the class name + * @return the entity class + */ + public Class getEntityClass(String className) + { + return getEntityNameToClassMap().get(className); + } + + /** + * Assign to managedTypes. + * + * @param managedTypes + * the managedTypes to set + */ + public void assignManagedTypes(Map, EntityType> managedTypes) + { + if (this.entityTypes == null) + { + this.entityTypes = managedTypes; + } + else + { + this.entityTypes.putAll(managedTypes); + } + } + + /** + * Assign embeddables to embeddables collection. + * + * @param embeddables + * the embeddables to set + */ + public void assignEmbeddables(Map, ManagedType> embeddables) + { + if (this.embeddables == null) + { + this.embeddables = embeddables; + } + else + { + this.embeddables.putAll(embeddables); + } + } + + /** + * Adds mapped super class to mapped super class collection. + * + * @param mappedSuperClass + * the mappedSuperClassTypes to set + */ + public void assignMappedSuperClass(Map, ManagedType> mappedSuperClass) + { + if (this.mappedSuperClassTypes == null) + { + this.mappedSuperClassTypes = mappedSuperClass; + } + else + { + this.mappedSuperClassTypes.putAll(mappedSuperClassTypes); + } + } + + /** + * Returns true, if attribute is embeddable. + * + * @param embeddableClazz + * class for embeddable type attribute. + * @return try, if paramterized class is of embeddable java type. + */ + public boolean isEmbeddable(Class embeddableClazz) + { + return embeddables != null ? embeddables.containsKey(embeddableClazz) + && embeddables.get(embeddableClazz).getPersistenceType().equals(PersistenceType.EMBEDDABLE) : false; + } + + /** + * Returns entity attribute for given managed entity class. + * + * @param clazz + * Entity class + * @param fieldName + * field name + * @return entity attribute + */ + public Attribute getEntityAttribute(Class clazz, String fieldName) + { + if (entityTypes != null && entityTypes.containsKey(clazz)) + { + EntityType entityType = entityTypes.get(clazz); + return entityType.getAttribute(fieldName); + } + + throw new IllegalArgumentException("No entity found: " + clazz); + } + + /** + * Custome implementation to offer map of embeddables available for given + * entityType. + * + * @param clazz + * entity class + * @return map of holding {@link EmbeddableType} as value and attribute name + * as key. + */ + public Map getEmbeddables(Class clazz) + { + Map embeddableAttibutes = new HashMap(); + + if (entityTypes != null) + { + EntityType entity = entityTypes.get(clazz); + Iterator iter = entity.getAttributes().iterator(); + while (iter.hasNext()) + { + Attribute attribute = iter.next(); + if (isEmbeddable(((AbstractAttribute) attribute).getBindableJavaType())) + { + embeddableAttibutes.put(attribute.getName(), + embeddable(((AbstractAttribute) attribute).getBindableJavaType())); + } + + } + + } + return embeddableAttibutes; + } + + /** + * @return the keyValues + */ + public IdDiscriptor getKeyValue(String entityName) + { + if (keyValues != null) + { + return this.keyValues.get(entityName); + } + return null; + } + + /** + * @param keyValues + * the keyValues to set + */ + public void addKeyValues(Map keyDiscriptors) + { + if (keyValues == null) + { + keyValues = new HashMap(); + } + this.keyValues.putAll(keyDiscriptors); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PersistenceUnitMetadata.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PersistenceUnitMetadata.java new file mode 100644 index 000000000..926d44e59 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PersistenceUnitMetadata.java @@ -0,0 +1,589 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.SharedCacheMode; +import javax.persistence.ValidationMode; +import javax.persistence.spi.ClassTransformer; +import javax.persistence.spi.PersistenceUnitInfo; +import javax.persistence.spi.PersistenceUnitTransactionType; +import javax.sql.DataSource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.loader.PersistenceLoaderException; + +/** + * The Class PersistenceUnitMetadata. + * + * @author amresh.singh + */ +public class PersistenceUnitMetadata implements PersistenceUnitInfo +{ + /** logger instance. */ + private static Logger log = LoggerFactory.getLogger(PersistenceUnitMetadata.class); + + /** Persistence Unit name. */ + private String persistenceUnitName; + + /** The provider. */ + private String provider; + + /** The transaction type. */ + private PersistenceUnitTransactionType transactionType; + + /** The classes. */ + private List classes = new ArrayList(); + + /** The packages. */ + private List packages = new ArrayList(); + + /** The jar files. */ + private Set jarFiles; + + private Set jarUrls; + + /** The properties. */ + private Properties properties = new Properties(); + + /** The exclude unlisted classes. */ + private boolean excludeUnlistedClasses = false; + + private URL rootUrl; + + private String schemaVersion; + + private URL mappedUrl; + + public PersistenceUnitMetadata() + { + + } + + public PersistenceUnitMetadata(String xmlSchemaVersion, URL rootUrl, URL mappingFileUrl) + { + this.schemaVersion = xmlSchemaVersion; + this.rootUrl = rootUrl; + this.mappedUrl = mappingFileUrl; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getPersistenceUnitName() + */ + @Override + public String getPersistenceUnitName() + { + return persistenceUnitName; + } + + /** + * Sets the persistence unit name. + * + * @param persistenceUnitName + * the persistenceUnitName to set + */ + public void setPersistenceUnitName(String persistenceUnitName) + { + this.persistenceUnitName = persistenceUnitName; + } + + /** + * Sets the transaction type. + * + * @param transactionType + * the new transaction type + */ + public void setTransactionType(PersistenceUnitTransactionType transactionType) + { + this.transactionType = transactionType; + } + + // /** + // * Gets the provider. + // * + // * @return the provider + // */ + // public String getProvider() + // { + // return provider; + // } + + /** + * Sets the provider. + * + * @param provider + * the new provider + */ + public void setProvider(String provider) + { + if (provider != null && provider.endsWith(".class")) + { + this.provider = provider.substring(0, provider.length() - 6); + } + this.provider = provider; + } + + /** + * Gets the classes. + * + * @return the classes + */ + public List getClasses() + { + return classes; + } + + /** + * Sets the classes. + * + * @param classes + * the new classes + */ + public void setClasses(List classes) + { + this.classes = classes; + } + + /** + * Gets the packages. + * + * @return the packages + */ + public List getPackages() + { + return packages; + } + + /** + * Sets the packages. + * + * @param packages + * the new packages + */ + public void setPackages(List packages) + { + this.packages = packages; + } + + /** + * Gets the jar files. + * + * @return the jar files + */ + public Set getJarFiles() + { + return jarFiles; + } + + /** + * Sets the jar files. + * + * @param jarFiles + * the new jar files + */ + public void addJarFile(String jarFile) + { + if (jarFiles == null) + { + jarFiles = new HashSet(); + } + this.jarFiles.add(jarFile); + addJarFileUrl(jarFile); + + } + + /** + * Gets the exclude unlisted classes. + * + * @return the exclude unlisted classes + */ + public boolean getExcludeUnlistedClasses() + { + return excludeUnlistedClasses; + } + + /** + * Sets the exclude unlisted classes. + * + * @param excludeUnlistedClasses + * the new exclude unlisted classes + */ + public void setExcludeUnlistedClasses(boolean excludeUnlistedClasses) + { + this.excludeUnlistedClasses = excludeUnlistedClasses; + } + + /* @see java.lang.Object#toString() */ + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append("PersistenceMetadata [name="); + builder.append(persistenceUnitName); + builder.append(", provider="); + builder.append(provider); + builder.append(", transactionType="); + builder.append(transactionType); + builder.append(", classes="); + builder.append(classes); + builder.append(", excludeUnlistedClasses="); + builder.append(excludeUnlistedClasses); + builder.append(", jarFiles="); + builder.append(jarFiles); + builder.append(", packages="); + builder.append(packages); + builder.append(", props="); + builder.append(properties); + builder.append("]"); + return builder.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.spi.PersistenceUnitInfo#getPersistenceProviderClassName + * () + */ + @Override + public String getPersistenceProviderClassName() + { + return provider; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getTransactionType() + */ + @Override + public PersistenceUnitTransactionType getTransactionType() + { + return transactionType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getJtaDataSource() + */ + @Override + public DataSource getJtaDataSource() + { + return null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getNonJtaDataSource() + */ + @Override + public DataSource getNonJtaDataSource() + { + return null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getMappingFileNames() + */ + @Override + public List getMappingFileNames() + { + return null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getJarFileUrls() + */ + @Override + public List getJarFileUrls() + { + return jarUrls != null ? new ArrayList(jarUrls) : null; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.spi.PersistenceUnitInfo#getPersistenceUnitRootUrl() + */ + @Override + public URL getPersistenceUnitRootUrl() + { + return rootUrl; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getManagedClassNames() + */ + @Override + public List getManagedClassNames() + { + return classes; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#excludeUnlistedClasses() + */ + @Override + public boolean excludeUnlistedClasses() + { + return excludeUnlistedClasses; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getSharedCacheMode() + */ + @Override + public SharedCacheMode getSharedCacheMode() + { + return null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getValidationMode() + */ + @Override + public ValidationMode getValidationMode() + { + return null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getProperties() + */ + @Override + public Properties getProperties() + { + if (this.properties == null) + { + throw new PersistenceLoaderException(" Error while loading metadata as perssitenceUnitMetadata is null"); + } + return this.properties; + } + + /** + * Sets the properties. + * + * @param properties + * the properties to set + */ + public void setProperties(Properties properties) + { + this.properties = properties; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.spi.PersistenceUnitInfo#getPersistenceXMLSchemaVersion + * () + */ + @Override + public String getPersistenceXMLSchemaVersion() + { + return schemaVersion; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getClassLoader() + */ + @Override + public ClassLoader getClassLoader() + { + return this.getClass().getClassLoader(); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.spi.PersistenceUnitInfo#addTransformer(javax.persistence + * .spi.ClassTransformer) + */ + @Override + public void addTransformer(ClassTransformer paramClassTransformer) + { + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.spi.PersistenceUnitInfo#getNewTempClassLoader() + */ + @Override + public ClassLoader getNewTempClassLoader() + { + return null; + } + + /** + * Gets the property. + * + * @param prop + * the prop + * @return the property + */ + public String getProperty(String prop) + { + // assuming Properties are initialized with this call + return prop != null ? getProperties().getProperty(prop) : null; + } + + /** + * Returns list of managed urls. + * + * @return + */ + public List getManagedURLs() + { + // should we cache it? + List managedURL = getJarFileUrls(); + if (managedURL == null) + { + managedURL = new ArrayList(1); + } + + if (!getExcludeUnlistedClasses()) + { + managedURL.add(getPersistenceUnitRootUrl()); + } + return managedURL; + } + + /** + * Adds jar file URL. + * + * @param jarFile + * jar file path + */ + private void addJarFileUrl(String jarFile) + { + if (jarUrls == null) + { + jarUrls = new HashSet(); + } + try + { + jarUrls.add(new File(jarFile).toURI().toURL()); + } + catch (MalformedURLException e) + { + log.error("Error while mapping jar-file url" + jarFile + "caused by:" + e.getMessage()); + throw new IllegalArgumentException("Invalid jar-file URL:" + jarFile + "Caused by: " + e); + } + } + + /** + * Gets the client. In case client is not configure, it throws + * IllegalArgumentException. + * + * @return the client + */ + public String getClient() + { + String client = null; + if (this.properties != null) + { + client = (String) this.properties.get(PersistenceProperties.KUNDERA_CLIENT_FACTORY); + } + + if (client == null) + { + log.error("kundera.client property is missing for persistence unit:" + persistenceUnitName); + throw new IllegalArgumentException("kundera.client property is missing for persistence unit:" + + persistenceUnitName); + } + + return client; + } + + /** + * Returns true, if pu is specified with batch size. + * + * @return true, if pu consists batch.size property. + */ + private boolean isBatch() + { + return getProperty(PersistenceProperties.KUNDERA_BATCH_SIZE) != null; + } + + /** + * Return batch.size value. + * + * @return integer value for batch size. + */ + public int getBatchSize() + { + if (isBatch()) + { + String batchSize = getProperty(PersistenceProperties.KUNDERA_BATCH_SIZE); + int batch_Size = Integer.valueOf(batchSize); + if (batch_Size == 0) + { + throw new IllegalArgumentException("kundera.batch.size property must be numeric and > 0"); + } + return batch_Size; + } + + return 0; + } + + /** + * @return the mappedUrl + */ + public URL getMappedUrl() + { + return mappedUrl; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PropertyIndex.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PropertyIndex.java new file mode 100644 index 000000000..58acdb260 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/PropertyIndex.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; + +/** + * Contains Index information of a field. + * + * @author animesh.kumar + */ +public final class PropertyIndex +{ + + /** The name. */ + private String name; + + /** The property. */ + private Field property; + + private String indexType; + + /** The boost. */ + private float boost = 1.0f; + + private Integer max; + + private Integer min; + + // /** + // * The Constructor. + // * + // * @param property + // * the property + // */ + // public PropertyIndex(Field property) + // { + // this.property = property; + // this.name = property.getName(); + // } + + public PropertyIndex() + { + + } + + /** + * Instantiates a new property index. + * + * @param property + * the property + * @param name + * the name + */ + public PropertyIndex(Field property, String name, String indexType) + { + this.property = property; + this.name = name; + this.indexType = indexType; + } + + /** + * Gets the name. + * + * @return the name + */ + public String getName() + { + return name; + } + + /** + * Gets the property. + * + * @return the property + */ + public Field getProperty() + { + return property; + } + + /** + * Gets the boost. + * + * @return the boost + */ + public float getBoost() + { + return boost; + } + + /** + * Sets the boost. + * + * @param boost + * the new boost + */ + public void setBoost(float boost) + { + this.boost = boost; + } + + /** + * @return the indexType + */ + public String getIndexType() + { + return indexType; + } + + /** + * @param indexType + * the indexType to set + */ + public void setIndexType(String indexType) + { + this.indexType = indexType; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @param property + * the property to set + */ + public void setProperty(Field property) + { + this.property = property; + } + + /** + * @return the max + */ + public Integer getMax() + { + return max; + } + + /** + * @param max + * the max to set + */ + public void setMax(Integer max) + { + this.max = max; + } + + /** + * @return the min + */ + public Integer getMin() + { + return min; + } + + /** + * @param min + * the min to set + */ + public void setMin(Integer min) + { + this.min = min; + } + +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Relation.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Relation.java new file mode 100644 index 000000000..f81ebd621 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/Relation.java @@ -0,0 +1,390 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.FetchType; + +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * The Class Relation. + */ +public final class Relation +{ + + /** The property. */ + private Field property; + + /** The target entity. */ + private Class targetEntity; + + /** If relation is through a Map, Map Key Join Class */ + private Class mapKeyJoinClass; + + /** The property type. */ + private Class propertyType; + + /** The fetch type. */ + FetchType fetchType; + + /** The cascades. */ + private List cascades; + + /** The optional. */ + private boolean optional; + + /** The mapped by. */ + private String mappedBy; + + /** The type. */ + private Relation.ForeignKey type; + + /** Join column name for this relationship. */ + private String joinColumnName; + + /** Whether this relationship is through a Join Table. */ + private boolean isRelatedViaJoinTable; + + /** Metadata for JoinTable, applicable only if isRelatedViaJoinTable==true. */ + private JoinTableMetadata joinTableMetadata; + + /** + * Whether this relationship is joined by primary key, only applicable for + * OneToOne. + */ + private boolean isJoinedByPrimaryKey; + + private Field biDirectionalField; + /** + * + * The Enum ForeignKey. + */ + public static enum ForeignKey + { + /** The ON e_ t o_ one. */ + ONE_TO_ONE, + /** The ON e_ t o_ many. */ + ONE_TO_MANY, + /** The MAN y_ t o_ one. */ + MANY_TO_ONE, + /** The MAN y_ t o_ many. */ + MANY_TO_MANY + } + + /** + * Instantiates a new relation. + * + * @param property + * the property + * @param targetEntity + * the target entity + * @param propertyType + * the property type + * @param fetchType + * the fetch type + * @param cascades + * the cascades + * @param optional + * the optional + * @param mappedBy + * the mapped by + * @param type + * the type + */ + + /** + * Specifies the type of the metadata. + */ + + public Relation(Field property, Class targetEntity, Class propertyType, FetchType fetchType, + List cascades, boolean optional, String mappedBy, Relation.ForeignKey type) + { + super(); + this.property = property; + this.targetEntity = targetEntity; + this.propertyType = propertyType; + this.fetchType = fetchType; + this.cascades = cascades; + this.optional = optional; + this.mappedBy = mappedBy; + this.type = type; + } + + /** + * Gets the property. + * + * @return the property + */ + public Field getProperty() + { + return property; + } + + /** + * Gets the target entity. + * + * @return the targetEntity + */ + public Class getTargetEntity() + { + return targetEntity; + } + + /** + * @return the mapKeyJoinClass + */ + public Class getMapKeyJoinClass() + { + return mapKeyJoinClass; + } + + /** + * @param mapKeyJoinClass + * the mapKeyJoinClass to set + */ + public void setMapKeyJoinClass(Class mapKeyJoinClass) + { + this.mapKeyJoinClass = mapKeyJoinClass; + } + + /** + * Gets the property type. + * + * @return the propertyType + */ + public Class getPropertyType() + { + return propertyType; + } + + /** + * Gets the fetch type. + * + * @return the fetchType + */ + public FetchType getFetchType() + { + return fetchType; + } + + /** + * Gets the cascades. + * + * @return the cascades + */ + public List getCascades() + { + return cascades; + } + + /** + * Checks if is optional. + * + * @return the optional + */ + public boolean isOptional() + { + return optional; + } + + /** + * Gets the mapped by. + * + * @return the mappedBy + */ + public String getMappedBy() + { + return mappedBy; + } + + /** + * Gets the type. + * + * @return the type + */ + public Relation.ForeignKey getType() + { + return type; + } + + /** + * Gets the join column name. + * + * @return the joinColumnName + */ + public String getJoinColumnName() + { + + if(joinColumnName == null && isJoinedByPrimaryKey) + { + EntityMetadata joinClassMetadata = KunderaMetadataManager.getEntityMetadata(targetEntity); + joinColumnName = ((AbstractAttribute)joinClassMetadata.getIdAttribute()).getJPAColumnName(); + } + + if(joinTableMetadata != null) + { + joinColumnName = joinTableMetadata.getJoinColumns() != null? joinTableMetadata.getJoinColumns().iterator().next():null; + } + + return joinColumnName !=null? joinColumnName:property.getName(); + } + + /** + * Sets the join column name. + * + * @param joinColumnName + * the joinColumnName to set + */ + public void setJoinColumnName(String joinColumnName) + { + this.joinColumnName = joinColumnName; + } + + /** + * Checks if is related via join table. + * + * @return the isRelatedViaJoinTable + */ + public boolean isRelatedViaJoinTable() + { + return isRelatedViaJoinTable; + } + + /** + * Sets the related via join table. + * + * @param isRelatedViaJoinTable + * the isRelatedViaJoinTable to set + */ + public void setRelatedViaJoinTable(boolean isRelatedViaJoinTable) + { + this.isRelatedViaJoinTable = isRelatedViaJoinTable; + } + + /** + * Gets the join table metadata. + * + * @return the joinTableMetadata + */ + public JoinTableMetadata getJoinTableMetadata() + { + return joinTableMetadata; + } + + /** + * Sets the join table metadata. + * + * @param joinTableMetadata + * the joinTableMetadata to set + */ + public void setJoinTableMetadata(JoinTableMetadata joinTableMetadata) + { + this.joinTableMetadata = joinTableMetadata; + } + + /** + * Checks if is joined by primary key. + * + * @return the isJoinedByPrimaryKey + */ + public boolean isJoinedByPrimaryKey() + { + return isJoinedByPrimaryKey; + } + + /** + * Sets the joined by primary key. + * + * @param isJoinedByPrimaryKey + * the isJoinedByPrimaryKey to set + */ + public void setJoinedByPrimaryKey(boolean isJoinedByPrimaryKey) + { + this.isJoinedByPrimaryKey = isJoinedByPrimaryKey; + } + + /** + * Checks if is unary. + * + * @return true, if is unary + */ + public boolean isUnary() + { + return type.equals(Relation.ForeignKey.ONE_TO_ONE) || type.equals(Relation.ForeignKey.MANY_TO_ONE); + } + + /** + * Checks if is collection. + * + * @return true, if is collection + */ + public boolean isCollection() + { + return type.equals(Relation.ForeignKey.ONE_TO_MANY) || type.equals(Relation.ForeignKey.MANY_TO_MANY); + } + + + public boolean isBiDirectional() + { + return biDirectionalField != null; + } + + public Field getBiDirectionalField() + { + return biDirectionalField; + } + + public void setBiDirectionalField(Class referencedClass) + { + Field[] fields = this.getTargetEntity().getDeclaredFields(); + Class clazzz = null; + for (Field field : fields) + { + if (!ReflectUtils.isTransientOrStatic(field)) + { + clazzz = field.getType(); + if (PropertyAccessorHelper.isCollection(clazzz)) + { + ParameterizedType type = (ParameterizedType) field.getGenericType(); + Type[] types = type.getActualTypeArguments(); + clazzz = (Class) types[0]; + } + else if (Map.class.isAssignableFrom(clazzz)) + { + ParameterizedType type = (ParameterizedType) field.getGenericType(); + Type[] types = type.getActualTypeArguments(); + clazzz = (Class) types[1]; + } + if (clazzz.equals(referencedClass)) + { + biDirectionalField = field; + break; + } + } + } + + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/SequenceGeneratorDiscriptor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/SequenceGeneratorDiscriptor.java new file mode 100644 index 000000000..34ed4dd5e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/SequenceGeneratorDiscriptor.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import javax.persistence.SequenceGenerator; + +/** + * SequenceGeneratorDiscriptor class holds the information about sequence + * generator. + * + * @author Kuldeep.Mishra + * + */ +public class SequenceGeneratorDiscriptor +{ + private static final int default_initial_value = 1; + + private static final String default_sequence_name = "sequence_name"; + + private static final int default_allocation_size = 50; + + private int initialValue; + + private int allocationSize; + + private String sequenceName; + + private String schemaName; + + private String catalog; + + public SequenceGeneratorDiscriptor(SequenceGenerator sequenceGenerator, String defaultSchemaName) + { + this.initialValue = sequenceGenerator.initialValue(); + this.allocationSize = sequenceGenerator.allocationSize(); + this.sequenceName = sequenceGenerator.sequenceName().isEmpty() ? default_sequence_name : sequenceGenerator + .sequenceName(); + this.schemaName = sequenceGenerator.schema().isEmpty() ? defaultSchemaName : sequenceGenerator.schema(); + } + + public SequenceGeneratorDiscriptor(String defaultSchemaName) + { + this.initialValue = default_initial_value; + this.allocationSize = default_allocation_size; + this.sequenceName = default_sequence_name; + this.schemaName = defaultSchemaName; + } + + /** + * @return the initialValue + */ + public int getInitialValue() + { + return initialValue; + } + + /** + * @return the allocationSize + */ + public int getAllocationSize() + { + return allocationSize; + } + + /** + * @return the sequenceName + */ + public String getSequenceName() + { + return sequenceName; + } + + /** + * @return the schemaName + */ + public String getSchemaName() + { + return schemaName; + } + + /** + * @return the catalog + */ + public String getCatalog() + { + return catalog; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/TableGeneratorDiscriptor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/TableGeneratorDiscriptor.java new file mode 100644 index 000000000..e2d8ad7db --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/TableGeneratorDiscriptor.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model; + +import javax.persistence.TableGenerator; +import javax.persistence.UniqueConstraint; + +/** + * TableGeneratorDiscriptor class holds the information about table generator. + * + * @author Kuldeep.Mishra + * + */ +public class TableGeneratorDiscriptor +{ + private static final String default_table_name = "kundera_sequences"; + + private static final String default_pkColumn_name = "sequence_name"; + + private static final String default_valueColumn_name = "sequence_value"; + + private static final int default_allocation_size = 50; + + private static final int default_initial_value = 1; + + private String table; + + private String catalog; + + private String schema; + + private String pkColumnName; + + private String valueColumnName; + + private String pkColumnValue; + + private int initialValue; + + private int allocationSize; + + private UniqueConstraint[] uniqueConstraints; + + public TableGeneratorDiscriptor(TableGenerator tableGenerator, String defaultSchemaName, String defaultPkColumnValue) + { + this.table = tableGenerator.table().isEmpty() ? default_table_name : tableGenerator.table(); + this.schema = tableGenerator.schema().isEmpty() ? defaultSchemaName : tableGenerator.schema(); + this.pkColumnName = tableGenerator.pkColumnName().isEmpty() ? default_pkColumn_name : tableGenerator + .pkColumnName(); + this.valueColumnName = tableGenerator.valueColumnName().isEmpty() ? default_valueColumn_name : tableGenerator + .valueColumnName(); + this.pkColumnValue = tableGenerator.pkColumnValue().isEmpty() ? defaultPkColumnValue : tableGenerator + .pkColumnValue(); + this.initialValue = tableGenerator.initialValue(); + this.allocationSize = tableGenerator.allocationSize(); + } + + public TableGeneratorDiscriptor(String defaultSchemaName, String defaultPkColumnValue) + { + this.table = default_table_name; + this.schema = defaultSchemaName; + this.pkColumnName = default_pkColumn_name; + this.valueColumnName = default_valueColumn_name; + this.pkColumnValue = defaultPkColumnValue; + this.initialValue = default_initial_value; + this.allocationSize = default_allocation_size; + } + + /** + * @return the table + */ + public String getTable() + { + return table; + } + + /** + * @return the catalog + */ + public String getCatalog() + { + return catalog; + } + + /** + * @return the schema + */ + public String getSchema() + { + return schema; + } + + /** + * @return the pkColumnName + */ + public String getPkColumnName() + { + return pkColumnName; + } + + /** + * @return the valueColumnName + */ + public String getValueColumnName() + { + return valueColumnName; + } + + /** + * @return the pkColumnValue + */ + public String getPkColumnValue() + { + return pkColumnValue; + } + + /** + * @return the initialValue + */ + public int getInitialValue() + { + return initialValue; + } + + /** + * @return the allocationSize + */ + public int getAllocationSize() + { + return allocationSize; + } + + /** + * @return the uniqueConstraints + */ + public UniqueConstraint[] getUniqueConstraints() + { + return uniqueConstraints; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractAttribute.java new file mode 100644 index 000000000..6131c4048 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractAttribute.java @@ -0,0 +1,235 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; +import java.lang.reflect.Member; +import java.util.Date; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.JoinColumn; +import javax.persistence.Temporal; +import javax.persistence.metamodel.Attribute.PersistentAttributeType; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Type; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract class for to provide generalisation, abstraction to + * Type hierarchy. + * + * @param + * the generic mananged entitytype + * @param + * the generic attribute type + * @author vivek.mishra + */ +public abstract class AbstractAttribute +{ + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(AbstractAttribute.class); + + /** The attrib type. */ + protected Type attribType; + + /** The attrib name. */ + private String attribName; + + /** The persistence attrib type. */ + private PersistentAttributeType persistenceAttribType; + + /** The managed type. */ + private ManagedType managedType; + + /** The member. */ + protected Field member; + + /** Column name */ + private String columnName; + + /** + * Instantiates a new abstract attribute. + * + * @param attribType + * the attrib type + * @param attribName + * the attrib name + * @param persistenceAttribType + * the persistence attrib type + * @param managedType + * the managed type + * @param member + * the member + */ + AbstractAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member) + { + + this.attribType = attribType; + this.attribName = attribName; + this.persistenceAttribType = persistenceAttribType; + this.managedType = managedType; + this.member = member; + this.columnName = getValidJPAColumnName(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Bindable#getBindableType() + */ + public abstract javax.persistence.metamodel.Bindable.BindableType getBindableType(); + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#isCollection() + */ + public abstract boolean isCollection(); + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Bindable#getBindableJavaType() + */ + public Class getBindableJavaType() + { + return attribType.getJavaType(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getName() + */ + public String getName() + { + return attribName; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getPersistentAttributeType() + */ + + public javax.persistence.metamodel.Attribute.PersistentAttributeType getPersistentAttributeType() + { + return persistenceAttribType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getDeclaringType() + */ + public ManagedType getDeclaringType() + { + return managedType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getJavaMember() + */ + public Member getJavaMember() + { + return member; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#isAssociation() + */ + public boolean isAssociation() + { + return persistenceAttribType.equals(PersistentAttributeType.MANY_TO_MANY) + || persistenceAttribType.equals(PersistentAttributeType.MANY_TO_ONE) + || persistenceAttribType.equals(PersistentAttributeType.ONE_TO_MANY) + || persistenceAttribType.equals(PersistentAttributeType.ONE_TO_ONE); + } + + /** + * Returns assigned jpa column name. + * + * @return column name jpa column name. + */ + public String getJPAColumnName() + { + return columnName; + } + + /** + * Gets the valid jpa column name. + * + * @param entity + * the entity + * @param f + * the f + * @return the valid jpa column name + */ + private final String getValidJPAColumnName() + { + + String name = null; + + if (member.isAnnotationPresent(Column.class)) + { + Column c = member.getAnnotation(Column.class); + if (!c.name().isEmpty()) + { + name = c.name(); + } + + } + if (member.isAnnotationPresent(Temporal.class)) + { + if (!member.getType().equals(Date.class)) + { + log.error("@Temporal must map to java.util.Date for @Entity(" + managedType.getJavaType() + "." + + member.getName() + ")"); + return name; + } + } + else if (member.isAnnotationPresent(JoinColumn.class)) + { + JoinColumn c = member.getAnnotation(JoinColumn.class); + if (!c.name().isEmpty()) + { + name = c.name(); + } + } + else if (member.isAnnotationPresent(CollectionTable.class)) + { + CollectionTable c = member.getAnnotation(CollectionTable.class); + if (!c.name().isEmpty()) + { + name = c.name(); + } + } + return name == null ? getName() : name; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractPluralAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractPluralAttribute.java new file mode 100644 index 000000000..bc6464ad9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AbstractPluralAttribute.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; + +import javax.persistence.metamodel.Bindable.BindableType; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.PluralAttribute; +import javax.persistence.metamodel.PluralAttribute.CollectionType; +import javax.persistence.metamodel.Type; + +/** + * Abstract class to provide generalisation to + * {@link PluralAttribute} interface. + * + * @author vivek.mishra + * + * @param + * managed entity java type. + * @param + * attribute's java type. + * @param + * Collection type of plural attributes. + */ +public abstract class AbstractPluralAttribute extends AbstractAttribute +{ + + private Class collectionClazz; + + /** + * Constructor with fields. + * + * @param attribType + * attribute type + * @param attribName + * attribute field's name + * @param persistenceAttribType + * persistent attribute type + * @param managedType + * type of managed entity. + * @param member + * java member. + */ + AbstractPluralAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member, Class clazz) + { + super(attribType, attribName, persistenceAttribType, managedType, member); + this.collectionClazz = clazz; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.metadata.model.attributes.AbstractAttribute# + * getBindableType() + */ + @Override + public javax.persistence.metamodel.Bindable.BindableType getBindableType() + { + return BindableType.PLURAL_ATTRIBUTE; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractAttribute#isCollection + * () + */ + @Override + public boolean isCollection() + { + return true; + } + + /** + * Return the collection type. + * + * @return collection type + */ + public abstract CollectionType getCollectionType(); + + /** + * Returns get java type. + * + * @return java type. + */ + protected Class getBoundJavaType() + { + return collectionClazz; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AttributeType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AttributeType.java new file mode 100644 index 000000000..aecb3af33 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/AttributeType.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.impetus.kundera.gis.geometry.Point; + +/** + * Attribute type. + * + * @author Kuldeep.Mishra + * + */ +public enum AttributeType +{ + ENUM, LIST, SET, MAP, POINT, PRIMITIVE; + + public static AttributeType getType(Class javaType) + { + AttributeType type = null; + if (javaType.isAssignableFrom(List.class)) + { + type = LIST; + } + else if (javaType.isAssignableFrom(Map.class)) + { + type = MAP; + } + else if (javaType.isAssignableFrom(Set.class)) + { + type = SET; + } + else if (javaType.isEnum()) + { + type = ENUM; + } + else if (javaType.isAssignableFrom(Point.class)) + { + type = POINT; + } + else + { + type = PRIMITIVE; + } + return type; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultCollectionAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultCollectionAttribute.java new file mode 100644 index 000000000..32b0c91ac --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultCollectionAttribute.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; +import java.util.Collection; + +import javax.persistence.metamodel.CollectionAttribute; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Type; + +/** + * Implementation class for {@link CollectionAttribute} + * interface. Offers metadata information implementation for collection + * attribute as per jpa. + * + * @author vivek.mishra + * + * @param + * Managed type + * @param + * collection's attribute type + */ +public class DefaultCollectionAttribute extends AbstractPluralAttribute> implements + CollectionAttribute +{ + + /** + * /** Constructor using fields. + * + * @param attribType + * attribute type + * @param attribName + * attribute name + * @param persistenceAttribType + * persistent attribute type. + * @param managedType + * managed type + * @param member + * attribute's java member. + */ + public DefaultCollectionAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member, Class> clazz) + { + super(attribType, attribName, persistenceAttribType, managedType, member, clazz); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getCollectionType() + */ + @Override + public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() + { + return CollectionType.COLLECTION; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getElementType() + */ + @Override + public Type getElementType() + { + return attribType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getJavaType() + */ + @Override + public Class> getJavaType() + { + return super.getBoundJavaType(); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultListAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultListAttribute.java new file mode 100644 index 000000000..7a7ce9aed --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultListAttribute.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; +import java.util.List; + +import javax.persistence.metamodel.ListAttribute; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Type; + +/** + * Implementation class for {@link ListAttribute} interface. + * Offers metadata information implementation for collection attribute as per + * jpa. + * + * @author vivek.mishra + * + * @param + * managed type + * @param + * attribute type of list attribute. + */ +public class DefaultListAttribute extends AbstractPluralAttribute> implements ListAttribute +{ + + /** + * Constructor using fields. + * + * @param attribType + * attribute type + * @param attribName + * attribute name + * @param persistenceAttribType + * persistent attribute type. + * @param managedType + * managed type + * @param member + * attribute's java member. + */ + public DefaultListAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member, Class> clazz) + { + super(attribType, attribName, persistenceAttribType, managedType, member, clazz); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getCollectionType() + */ + @Override + public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() + { + return CollectionType.LIST; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getElementType() + */ + @Override + public Type getElementType() + { + return attribType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getJavaType() + */ + @Override + public Class> getJavaType() + { + return super.getBoundJavaType(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultMapAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultMapAttribute.java new file mode 100644 index 000000000..a5ce16a68 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultMapAttribute.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; +import java.util.Map; + +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.MapAttribute; +import javax.persistence.metamodel.Type; + +/** + * Implementation class for {@link MapAttribute} interface. + * Offers metadata information implementation for collection attribute as per + * jpa. + * + * @author vivek.mishra + * + * @param + * managed type + * @param + * attribute type present in map. + */ +public class DefaultMapAttribute extends AbstractPluralAttribute> implements + MapAttribute +{ + + private Type keyType; + + /** + * Constructor using fields. + * + * @param attribType + * attribute type + * @param attribName + * attribute name + * @param persistenceAttribType + * persistent attribute type. + * @param managedType + * managed type + * @param member + * attribute's java member. + * @param key + * type attribute of key type. + */ + public DefaultMapAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member, Class> clazz, Type keyType) + { + super(attribType, attribName, persistenceAttribType, managedType, member, clazz); + this.keyType = keyType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.MapAttribute#getKeyJavaType() + */ + @Override + public Class getKeyJavaType() + { + return this.keyType.getJavaType(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.MapAttribute#getKeyType() + */ + @Override + public Type getKeyType() + { + return this.keyType; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getCollectionType() + */ + @Override + public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() + { + return CollectionType.MAP; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getElementType() + */ + @Override + public Type getElementType() + { + return attribType; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractAttribute#isCollection + * () + */ + @Override + public boolean isCollection() + { + return true; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getJavaType() + */ + @Override + public Class> getJavaType() + { + return super.getBoundJavaType(); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSetAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSetAttribute.java new file mode 100644 index 000000000..f104a7cc1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSetAttribute.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; +import java.util.Set; + +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.Type; + +/** + * Implementation class for {@link SetAttribute} interface. + * Offers metadata information implementation for collection attribute as per + * jpa. + * + * @author vivek.mishra + * + * @param + * managed type + * @param + * attribute type in set + */ +public class DefaultSetAttribute extends AbstractPluralAttribute> implements SetAttribute +{ + + /** + * Constructor using fields. + * + * @param attribType + * attribute type + * @param attribName + * attribute name + * @param persistenceAttribType + * persistent attribute type. + * @param managedType + * managed type + * @param member + * attribute's java member. + */ + public DefaultSetAttribute(Type attribType, String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, + ManagedType managedType, Field member, Class> clazz) + { + super(attribType, attribName, persistenceAttribType, managedType, member, clazz); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractPluralAttribute + * #getCollectionType() + */ + @Override + public javax.persistence.metamodel.PluralAttribute.CollectionType getCollectionType() + { + return CollectionType.SET; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.PluralAttribute#getElementType() + */ + @Override + public Type getElementType() + { + return this.attribType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#getJavaType() + */ + @Override + public Class> getJavaType() + { + return super.getBoundJavaType(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSingularAttribute.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSingularAttribute.java new file mode 100644 index 000000000..40e7bdea8 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/attributes/DefaultSingularAttribute.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.attributes; + +import java.lang.reflect.Field; + +import javax.persistence.Column; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.Type; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation class for {@link SetAttribute} interface. + * Offers metadata information implementation for collection attribute as per + * jpa. + * + * @author vivek.mishra + * + * @param + * managed type. + * @param + * attribute type. + */ + +public class DefaultSingularAttribute extends AbstractAttribute implements SingularAttribute +{ + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(DefaultSingularAttribute.class); + + /** Attribute is an id? */ + private boolean isId; + + /** + * @param attribName + * attribute name. + * @param persistenceAttribType + * persistent attribute type. + * @param member + * attribute's java member.. + * @param attribType + * attribute type. + * @param managedType + * managed type. + */ + public DefaultSingularAttribute(String attribName, + javax.persistence.metamodel.Attribute.PersistentAttributeType persistenceAttribType, Field member, + Type attribType, ManagedType managedType, boolean isId) + { + super(attribType, attribName, persistenceAttribType, managedType, member); + this.isId = isId; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Attribute#isCollection() + */ + @Override + public boolean isCollection() + { + return false; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Bindable#getBindableType() + */ + @Override + public javax.persistence.metamodel.Bindable.BindableType getBindableType() + { + return BindableType.SINGULAR_ATTRIBUTE; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.SingularAttribute#isId() + */ + @Override + public boolean isId() + { + return isId; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.SingularAttribute#isVersion() + */ + @Override + public boolean isVersion() + { + log.info("Currently versioning is not supported in kundera, returning false as default"); + return false; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.SingularAttribute#isOptional() + */ + @Override + public boolean isOptional() + { + boolean isNullable = true; + if (!isId()) + { + Column anno = member.getAnnotation(Column.class); + if (anno != null) + { + isNullable = anno.nullable(); + } + } + else + { + isNullable = false; + } + return isNullable; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.SingularAttribute#getType() + */ + @Override + public Type getType() + { + return attribType; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.model.attributes.AbstractAttribute#getJavaType + * () + */ + @Override + public Class getJavaType() + { + return attribType.getJavaType(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractIdentifiableType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractIdentifiableType.java new file mode 100644 index 000000000..c28ad36a9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractIdentifiableType.java @@ -0,0 +1,244 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import java.util.Set; + +import javax.persistence.metamodel.IdentifiableType; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.Type; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract implementation for IdentifiableType. + * + * @param + * the generic type + * @author vivek.mishra + */ +public abstract class AbstractIdentifiableType extends AbstractManagedType implements IdentifiableType +{ + + /** The id attribute. */ + private SingularAttribute idAttribute; + + /** The is id class. */ + private boolean isIdClass; + + /** The id class attributes. */ + private Set> idClassAttributes; + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(AbstractIdentifiableType.class); + + /** + * Instantiates a new abstract identifiable type. + * + * @param clazz + * the clazz + * @param persistenceType + * the persistence type + * @param superClazzType + * the super clazz type + */ + AbstractIdentifiableType(Class clazz, javax.persistence.metamodel.Type.PersistenceType persistenceType, + AbstractIdentifiableType superClazzType) + { + super(clazz, persistenceType, superClazzType); + + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#getId(java.lang.Class) + */ + @Override + public SingularAttribute getId(Class paramClass) + { + if (idAttribute != null) + { + if (idAttribute.getJavaType().equals(paramClass) && !isIdClass) + { + return (SingularAttribute) idAttribute; + } + else + { + onError(); + } + } + else + { + + AbstractIdentifiableType superType = (AbstractIdentifiableType) getSupertype(); + if (superType != null) + { + return superType.getId(paramClass); + } + } + + onError(); + + return null; + + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.IdentifiableType#getDeclaredId(java.lang. + * Class) + */ + @Override + public SingularAttribute getDeclaredId(Class paramClass) + { + if (idAttribute != null) + { + if (idAttribute.getJavaType().equals(paramClass) && !isIdClass) + { + return (SingularAttribute) idAttribute; + } + } + + onError(); + return null; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.IdentifiableType#getVersion(java.lang.Class) + */ + @Override + public SingularAttribute getVersion(Class paramClass) + { + // TODO: Versioning not yet supported. + throw new UnsupportedOperationException("Method not supported"); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.IdentifiableType#getDeclaredVersion(java. + * lang.Class) + */ + @Override + public SingularAttribute getDeclaredVersion(Class paramClass) + { + // TODO: Versioning not yet supported. + throw new UnsupportedOperationException("Method not supported"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#getSupertype() + */ + @Override + public IdentifiableType getSupertype() + { + return (AbstractIdentifiableType) super.getSuperClazzType(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#hasSingleIdAttribute() + */ + @Override + public boolean hasSingleIdAttribute() + { + return !isIdClass && idAttribute != null; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#hasVersionAttribute() + */ + @Override + public boolean hasVersionAttribute() + { + log.warn("Versioning not yet supported. returning false, By default"); + return false; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#getIdClassAttributes() + */ + @Override + public Set> getIdClassAttributes() + { + if (isIdClass) + { + return idClassAttributes; + } + throw new IllegalArgumentException("The identifiable type does not have an id class"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.IdentifiableType#getIdType() + */ + @Override + public Type getIdType() + { + if (idAttribute != null && !isIdClass) + { + return idAttribute.getType(); + } + + return getSupertype().getIdType(); + } + + /** + * Adds the id attribute. + * + * @param idAttribute + * the id attribute + * @param isIdClass + * the is id class + * @param idClassAttributes + * the id class attributes + */ + public void addIdAttribute(SingularAttribute idAttribute, boolean isIdClass, + Set> idClassAttributes) + { + + this.idAttribute = idAttribute; + this.isIdClass = isIdClass; + this.idClassAttributes = idClassAttributes; + } + + /** + * On error. + */ + private void onError() + { + throw new IllegalArgumentException( + "id attribute of the given type is not declared in the identifiable type or if the identifiable type has an id class(e.g. @IdClass is in use)"); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractManagedType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractManagedType.java new file mode 100644 index 000000000..788e2d525 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractManagedType.java @@ -0,0 +1,1047 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.Bindable; +import javax.persistence.metamodel.CollectionAttribute; +import javax.persistence.metamodel.ListAttribute; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.MapAttribute; +import javax.persistence.metamodel.PluralAttribute; +import javax.persistence.metamodel.PluralAttribute.CollectionType; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; + +/** + * Implementation for ManagedType interface. + * + * @param + * the generic entity type. + * @author vivek.mishra + */ +public abstract class AbstractManagedType extends AbstractType implements ManagedType +{ + + /** The super clazz type. */ + private ManagedType superClazzType; + + /** The declared singluar attribs. */ + private Map> declaredSingluarAttribs; + + /** The declared plural attributes. */ + private Map> declaredPluralAttributes; + + /** + * Super constructor with arguments. + * + * @param clazz + * parameterised class. + * @param persistenceType + * persistenceType. + * @param superClazzType + * the super clazz type + * @param declaredSingluarAttribs + * the declared singluar attribs + * @param declaredPluralAttributes + * the declared plural attributes + */ + AbstractManagedType(Class clazz, javax.persistence.metamodel.Type.PersistenceType persistenceType, + ManagedType superClazzType) + { + super(clazz, persistenceType); + this.superClazzType = superClazzType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getAttributes() + */ + @Override + public Set> getAttributes() + { + Set> attributes = new HashSet>(); + + Set> declaredAttribs = getDeclaredAttributes(); + if (declaredAttribs != null) + { + attributes.addAll(declaredAttribs); + } + if (superClazzType != null) + { + attributes.addAll(superClazzType.getDeclaredAttributes()); + } + + return attributes; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getDeclaredAttributes() + */ + @Override + public Set> getDeclaredAttributes() + { + Set> attributes = new HashSet>(); + + if (declaredSingluarAttribs != null) + { + attributes.addAll(declaredSingluarAttribs.values()); + } + if (declaredPluralAttributes != null) + { + attributes.addAll(declaredPluralAttributes.values()); + } + + return attributes; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getSingularAttribute(java.lang + * .String, java.lang.Class) + */ + @Override + public SingularAttribute getSingularAttribute(String paramString, Class paramClass) + { + SingularAttribute attribute = getDeclaredSingularAttribute(paramString, paramClass, false); + if (superClazzType != null && attribute == null) + { + return superClazzType.getDeclaredSingularAttribute(paramString, paramClass); + } + checkForValid(paramString, attribute); + return attribute; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredSingularAttribute( + * java.lang.String, java.lang.Class) + */ + @SuppressWarnings("unchecked") + @Override + public SingularAttribute getDeclaredSingularAttribute(String paramString, Class paramClass) + { + return getDeclaredSingularAttribute(paramString, paramClass, true); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getSingularAttributes() + */ + @SuppressWarnings("unchecked") + @Override + public Set> getSingularAttributes() + { + Set> singularAttrib = new HashSet>(); + + if (superClazzType != null) + { + Set parentAttrib = superClazzType.getDeclaredSingularAttributes(); + + if (parentAttrib != null) + { + singularAttrib.addAll(parentAttrib); + } + } + + Set> declaredAttribSet = getDeclaredSingularAttributes(); + + if (declaredAttribSet != null) + { + singularAttrib.addAll(declaredAttribSet); + } + + return singularAttrib; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredSingularAttributes() + */ + @Override + public Set> getDeclaredSingularAttributes() + { + Set> declaredAttribSet = null; + if (declaredSingluarAttribs != null) + { + declaredAttribSet = new HashSet>(); + declaredAttribSet.addAll(declaredSingluarAttribs.values()); + } + return declaredAttribSet; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getCollection(java.lang.String, + * java.lang.Class) + */ + @SuppressWarnings("unchecked") + @Override + public CollectionAttribute getCollection(String paramName, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckCollectionAttribute(declaredAttrib, paramClass)) + { + return (CollectionAttribute) declaredAttrib; + } + + PluralAttribute superAttrib = getPluralAttriute(paramName); + + if (onCheckCollectionAttribute(superAttrib, paramClass)) + { + return (CollectionAttribute) superAttrib; + + } + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredCollection(java.lang + * .String, java.lang.Class) + */ + @Override + public CollectionAttribute getDeclaredCollection(String paramString, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramString); + + if (onCheckCollectionAttribute(declaredAttrib, paramClass)) + { + return (CollectionAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramString + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getSet(java.lang.String, + * java.lang.Class) + */ + @Override + public SetAttribute getSet(String paramName, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckSetAttribute(declaredAttrib, paramClass)) + { + return (SetAttribute) declaredAttrib; + } + + PluralAttribute superAttrib = getPluralAttriute(paramName); + + if (onCheckSetAttribute(superAttrib, paramClass)) + { + return (SetAttribute) superAttrib; + + } + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredSet(java.lang.String, + * java.lang.Class) + */ + @Override + public SetAttribute getDeclaredSet(String paramName, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckSetAttribute(declaredAttrib, paramClass)) + { + return (SetAttribute) declaredAttrib; + } + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getList(java.lang.String, + * java.lang.Class) + */ + @Override + public ListAttribute getList(String paramName, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckListAttribute(declaredAttrib, paramClass)) + { + return (ListAttribute) declaredAttrib; + } + + PluralAttribute superAttrib = getPluralAttriute(paramName); + + if (onCheckListAttribute(superAttrib, paramClass)) + { + return (ListAttribute) superAttrib; + + } + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredList(java.lang.String, + * java.lang.Class) + */ + @Override + public ListAttribute getDeclaredList(String paramName, Class paramClass) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckListAttribute(declaredAttrib, paramClass)) + { + return (ListAttribute) declaredAttrib; + } + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName + + " , type:" + paramClass); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getMap(java.lang.String, + * java.lang.Class, java.lang.Class) + */ + @Override + public MapAttribute getMap(String paramName, Class keyClazz, Class valueClazz) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckMapAttribute(declaredAttrib, valueClazz)) + { + if (valueClazz != null && valueClazz.equals(((MapAttribute) declaredAttrib).getKeyJavaType())) + { + return (MapAttribute) declaredAttrib; + + } + } + + PluralAttribute superAttrib = getPluralAttriute(paramName); + + if (onCheckMapAttribute(superAttrib, valueClazz)) + { + if (valueClazz != null && valueClazz.equals(((MapAttribute) superAttrib).getKeyJavaType())) + { + return (MapAttribute) superAttrib; + + } + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed MapAttribute type, for name:" + + paramName + " , value type:" + valueClazz + "key tpye:" + keyClazz); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredMap(java.lang.String, + * java.lang.Class, java.lang.Class) + */ + @Override + public MapAttribute getDeclaredMap(String paramName, Class keyClazz, Class valueClazz) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (onCheckMapAttribute(declaredAttrib, valueClazz)) + { + if (valueClazz != null && valueClazz.equals(((MapAttribute) declaredAttrib).getKeyJavaType())) + { + return (MapAttribute) declaredAttrib; + + } + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed MapAttribute type, for name:" + + paramName + " , value type:" + valueClazz + "key tpye:" + keyClazz); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getPluralAttributes() + */ + @Override + public Set> getPluralAttributes() + { + Set> pluralAttributes = new HashSet>(); + Set> declaredAttribSet = getDeclaredPluralAttributes(); + if (declaredAttribSet != null) + { + pluralAttributes.addAll(declaredAttribSet); + } + + if (superClazzType != null) + { + pluralAttributes.addAll(superClazzType.getDeclaredPluralAttributes()); + } + + return pluralAttributes; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredPluralAttributes() + */ + @Override + public Set> getDeclaredPluralAttributes() + { + Set> declaredAttribSet = null; + + if (declaredPluralAttributes != null) + { + declaredAttribSet = new HashSet>(); + declaredAttribSet.addAll(declaredPluralAttributes.values()); + } + return declaredAttribSet; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getAttribute(java.lang.String) + */ + @Override + public Attribute getAttribute(String paramName) + { + Attribute attribute = getDeclaredAttribute(paramName, false); + if (attribute == null && superClazzType != null) + { + attribute = superClazzType.getDeclaredAttribute(paramName); + } + + checkForValid(paramName, attribute); + return attribute; + + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredAttribute(java.lang + * .String) + */ + @Override + public Attribute getDeclaredAttribute(String paramName) + { + Attribute attribute = getDeclaredAttribute(paramName, true); + return attribute; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getSingularAttribute(java.lang + * .String) + */ + @Override + public SingularAttribute getSingularAttribute(String paramString) + { + SingularAttribute attribute = getSingularAttribute(paramString, true); + return attribute; + } + + private SingularAttribute getSingularAttribute(String paramString, boolean checkValidity) + { + SingularAttribute attribute = getDeclaredSingularAttribute(paramString, false); + + try + { + if (attribute == null && superClazzType != null) + { + attribute = superClazzType.getDeclaredSingularAttribute(paramString); + } + } + catch (IllegalArgumentException iaex) + { + attribute = null; + onValidity(paramString, checkValidity, attribute); + } + onValidity(paramString, checkValidity, attribute); + return attribute; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredSingularAttribute( + * java.lang.String) + */ + @Override + public SingularAttribute getDeclaredSingularAttribute(String paramString) + { + SingularAttribute attribute = getDeclaredSingularAttribute(paramString, true); + + return attribute; + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getCollection(java.lang.String) + */ + @Override + public CollectionAttribute getCollection(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isCollectionAttribute(declaredAttrib)) + { + return (CollectionAttribute) declaredAttrib; + } + + declaredAttrib = getPluralAttriute(paramName); + + if (isCollectionAttribute(declaredAttrib)) + { + return (CollectionAttribute) declaredAttrib; + + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredCollection(java.lang + * .String) + */ + @Override + public CollectionAttribute getDeclaredCollection(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isCollectionAttribute(declaredAttrib)) + { + return (CollectionAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getSet(java.lang.String) + */ + @Override + public SetAttribute getSet(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isSetAttribute(declaredAttrib)) + { + return (SetAttribute) declaredAttrib; + } + + declaredAttrib = getPluralAttriute(paramName); + + if (isSetAttribute(declaredAttrib)) + { + return (SetAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredSet(java.lang.String) + */ + @Override + public SetAttribute getDeclaredSet(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isSetAttribute(declaredAttrib)) + { + return (SetAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getList(java.lang.String) + */ + @Override + public ListAttribute getList(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isListAttribute(declaredAttrib)) + { + return (ListAttribute) declaredAttrib; + } + + declaredAttrib = getPluralAttriute(paramName); + + if (isListAttribute(declaredAttrib)) + { + return (ListAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredList(java.lang.String) + */ + @Override + public ListAttribute getDeclaredList(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isListAttribute(declaredAttrib)) + { + return (ListAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.ManagedType#getMap(java.lang.String) + */ + @Override + public MapAttribute getMap(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isMapAttribute(declaredAttrib)) + { + return (MapAttribute) declaredAttrib; + } + + declaredAttrib = getPluralAttriute(paramName); + + if (isMapAttribute(declaredAttrib)) + { + return (MapAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.metamodel.ManagedType#getDeclaredMap(java.lang.String) + */ + @Override + public MapAttribute getDeclaredMap(String paramName) + { + PluralAttribute declaredAttrib = getDeclaredPluralAttribute(paramName); + + if (isMapAttribute(declaredAttrib)) + { + return (MapAttribute) declaredAttrib; + } + + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + } + + ManagedType getSuperClazzType() + { + return superClazzType; + } + + public void addSingularAttribute(String attributeName, SingularAttribute attribute) + { + if (declaredSingluarAttribs == null) + { + declaredSingluarAttribs = new HashMap>(); + } + + declaredSingluarAttribs.put(attributeName, attribute); + } + + public void addPluralAttribute(String attributeName, PluralAttribute attribute) + { + if (declaredPluralAttributes == null) + { + declaredPluralAttributes = new HashMap>(); + } + + declaredPluralAttributes.put(attributeName, attribute); + } + + /** + * Gets the declared plural attribute. + * + * @param paramName + * the param name + * @return the declared plural attribute + */ + private PluralAttribute getDeclaredPluralAttribute(String paramName) + { + return declaredPluralAttributes != null ? declaredPluralAttributes.get(paramName) : null; + } + + /** + * Gets the plural attriute. + * + * @param paramName + * the param name + * @return the plural attriute + */ + private PluralAttribute getPluralAttriute(String paramName) + { + if (superClazzType != null) + { + return ((AbstractManagedType) superClazzType).getDeclaredPluralAttribute(paramName); + } + return null; + } + + /** + * On check collection attribute. + * + * @param + * the element type + * @param pluralAttribute + * the plural attribute + * @param paramClass + * the param class + * @return true, if successful + */ + private boolean onCheckCollectionAttribute(PluralAttribute pluralAttribute, Class paramClass) + { + if (pluralAttribute != null) + { + if (isCollectionAttribute(pluralAttribute) && isBindable(pluralAttribute, paramClass)) + { + return true; + } + + } + + return false; + } + + /** + * On check set attribute. + * + * @param + * the element type + * @param pluralAttribute + * the plural attribute + * @param paramClass + * the param class + * @return true, if successful + */ + private boolean onCheckSetAttribute(PluralAttribute pluralAttribute, Class paramClass) + { + if (pluralAttribute != null) + { + if (isSetAttribute(pluralAttribute) && isBindable(pluralAttribute, paramClass)) + { + return true; + } + + } + + return false; + } + + /** + * On check list attribute. + * + * @param + * the element type + * @param pluralAttribute + * the plural attribute + * @param paramClass + * the param class + * @return true, if successful + */ + private boolean onCheckListAttribute(PluralAttribute pluralAttribute, Class paramClass) + { + if (pluralAttribute != null) + { + if (isListAttribute(pluralAttribute) && isBindable(pluralAttribute, paramClass)) + { + return true; + } + + } + + return false; + } + + /** + * On check map attribute. + * + * @param + * the value type + * @param pluralAttribute + * the plural attribute + * @param valueClazz + * the value clazz + * @return true, if successful + */ + private boolean onCheckMapAttribute(PluralAttribute pluralAttribute, Class valueClazz) + { + if (pluralAttribute != null) + { + if (isMapAttribute(pluralAttribute) && isBindable(pluralAttribute, valueClazz)) + { + return true; + } + + } + + return false; + } + + /** + * Checks if is collection attribute. + * + * @param attribute + * the attribute + * @return true, if is collection attribute + */ + private boolean isCollectionAttribute(PluralAttribute attribute) + { + return attribute != null && attribute.getCollectionType().equals(CollectionType.COLLECTION); + } + + /** + * Checks if is list attribute. + * + * @param attribute + * the attribute + * @return true, if is list attribute + */ + private boolean isListAttribute(PluralAttribute attribute) + { + return attribute != null && attribute.getCollectionType().equals(CollectionType.LIST); + } + + /** + * Checks if is sets the attribute. + * + * @param attribute + * the attribute + * @return true, if is sets the attribute + */ + private boolean isSetAttribute(PluralAttribute attribute) + { + return attribute != null && attribute.getCollectionType().equals(CollectionType.SET); + } + + /** + * Checks if is map attribute. + * + * @param attribute + * the attribute + * @return true, if is map attribute + */ + private boolean isMapAttribute(PluralAttribute attribute) + { + return attribute != null && attribute.getCollectionType().equals(CollectionType.MAP); + } + + /** + * Checks if is bindable. + * + * @param + * the element type + * @param attribute + * the attribute + * @param elementType + * the element type + * @return true, if is bindable + */ + private boolean isBindable(Bindable attribute, Class elementType) + { + return attribute != null && attribute.getBindableJavaType().equals(elementType); + } + + /** + * Check for valid. + * + * @param paramName + * the param name + * @param attribute + * the attribute + */ + private void checkForValid(String paramName, Attribute attribute) + { + if (attribute == null) + { + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramName); + + } + } + + /** + * @param paramName + * @param checkValidity + * @return + */ + private Attribute getDeclaredAttribute(String paramName, boolean checkValidity) + { + Attribute attribute = (Attribute) getSingularAttribute(paramName, false); + + if (attribute == null) + { + attribute = (Attribute) getDeclaredPluralAttribute(paramName); + } + + if (checkValidity) + { + checkForValid(paramName, attribute); + } + return attribute; + } + + /** + * Returns declared singular attribute. + * + * @param + * @param paramString + * @param paramClass + * @param checkValidity + * @return + */ + private SingularAttribute getDeclaredSingularAttribute(String paramString, Class paramClass, + boolean checkValidity) + { + SingularAttribute declaredAttrib = declaredSingluarAttribs.get(paramString); + + if (declaredAttrib != null && declaredAttrib.getBindableJavaType().equals(paramClass)) + { + return (SingularAttribute) declaredAttrib; + } + + if (checkValidity) + { + throw new IllegalArgumentException( + "attribute of the given name and type is not present in the managed type, for name:" + paramString + + " , type:" + paramClass); + } + return null; + } + + /** + * Returns declared singular attribute. + * + * @param paramString + * @param checkValidity + * @return + */ + private SingularAttribute getDeclaredSingularAttribute(String paramString, boolean checkValidity) + { + SingularAttribute attribute = null; + if (declaredSingluarAttribs != null) + { + attribute = declaredSingluarAttribs.get(paramString); + } + + if (checkValidity) + { + checkForValid(paramString, attribute); + } + return attribute; + } + + /** + * On validity check + * + * @param paramString + * @param checkValidity + * @param attribute + */ + private void onValidity(String paramString, boolean checkValidity, SingularAttribute attribute) + { + if (checkValidity) + { + checkForValid(paramString, attribute); + + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractType.java new file mode 100644 index 000000000..619680609 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/AbstractType.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import javax.persistence.metamodel.Type; + +/** + * Implements Type interface of MetaModel API. + * + * @param + * the generic type + * + * @author vivek.mishra + */ +public abstract class AbstractType implements Type +{ + + /** The clazz type. */ + private Class clazzType; + + /** The persistence type. */ + private PersistenceType persistenceType; + + /** + * Instantiates a new default type. + * + * @param clazz + * the clazz + * @param persistenceType + * the persistence type + */ + AbstractType(Class clazz, PersistenceType persistenceType) + { + this.clazzType = clazz; + this.persistenceType = persistenceType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Type#getPersistenceType() + */ + @Override + public javax.persistence.metamodel.Type.PersistenceType getPersistenceType() + { + return this.persistenceType; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Type#getJavaType() + */ + @Override + public Class getJavaType() + { + return this.clazzType; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultBasicType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultBasicType.java new file mode 100644 index 000000000..15b4273fd --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultBasicType.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import javax.persistence.metamodel.BasicType; +import javax.persistence.metamodel.Type; + +/** + * Default implementation of {@link BasicType} + * + * DefaultBasicType implements BasicType interface, + * invokes constructor with PersistenceType.BASIC. Default implementation of + * {@link Type} interface is provided by {@link AbstractType} + * + * @author vivek.mishra + * + */ +public class DefaultBasicType extends AbstractType implements BasicType +{ + + /** + * Constructor with arguments. + * + * @param clazz + * typed class. + */ + public DefaultBasicType(Class clazz) + { + super(clazz, PersistenceType.BASIC); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEmbeddableType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEmbeddableType.java new file mode 100644 index 000000000..a158403e8 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEmbeddableType.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Type; + +/** + * Default implementation of {@link EmbeddableType} + * + * DefaultEmbeddableType implements EmbeddableType + * interface, invokes constructor with PersistenceType.EMBEDDABLE. Default + * implementation of {@link Type} interface is provided by {@link AbstractType} + * + * @author vivek.mishra + * @param + * Embeddable generic java type. + */ +public class DefaultEmbeddableType extends AbstractManagedType implements EmbeddableType +{ + + /** + * Default constructor using fields. + */ + public DefaultEmbeddableType(Class clazz, javax.persistence.metamodel.Type.PersistenceType persistenceType, + ManagedType superClazzType) + { + super(clazz, persistenceType, superClazzType); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEntityType.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEntityType.java new file mode 100644 index 000000000..ca7549ec1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultEntityType.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Type; + +/** + * Default implementation of {@link EntityType} + * + * DefaultEmbeddableType implements EntityType + * interface, invokes constructor with PersistenceType.ENTITY. Default + * implementation of {@link Type} interface is provided by {@link AbstractType} + * + * @author vivek.mishra + * @param + * Entity generic java type. + */ + +public class DefaultEntityType extends AbstractIdentifiableType implements EntityType +{ + + /** + * Default constructor using fields. + */ + public DefaultEntityType(Class clazz, javax.persistence.metamodel.Type.PersistenceType persistenceType, + AbstractIdentifiableType superClazzType) + { + super(clazz, persistenceType, superClazzType); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Bindable#getBindableType() + */ + @Override + public javax.persistence.metamodel.Bindable.BindableType getBindableType() + { + return BindableType.ENTITY_TYPE; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.Bindable#getBindableJavaType() + */ + @Override + public Class getBindableJavaType() + { + return super.getJavaType(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.metamodel.EntityType#getName() + */ + @Override + public String getName() + { + return getBindableJavaType().getSimpleName(); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultMappedSuperClass.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultMappedSuperClass.java new file mode 100644 index 000000000..1d7004147 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/model/type/DefaultMappedSuperClass.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.model.type; + +import javax.persistence.metamodel.MappedSuperclassType; +import javax.persistence.metamodel.Type; + +/** + * Default implementation of {@link MappedSuperclassType} + * + * DefaultMappedSuperClass implements + * MappedSuperclassType interface, invokes constructor with + * PersistenceType.MAPPED_SUPERCLASS. Default implementation of {@link Type} + * interface is provided by {@link AbstractType} + * + * @author vivek.mishra + * @param + * Embeddable generic java type. + */ +public class DefaultMappedSuperClass extends AbstractIdentifiableType implements MappedSuperclassType +{ + + /** + * Default constructor using fields. + */ + public DefaultMappedSuperClass(Class clazz, javax.persistence.metamodel.Type.PersistenceType persistenceType, + AbstractIdentifiableType superClazzType) + { + super(clazz, persistenceType, superClazzType); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/AbstractEntityFieldProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/AbstractEntityFieldProcessor.java new file mode 100644 index 000000000..b9d3014f8 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/AbstractEntityFieldProcessor.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.util.Date; + +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.PersistenceException; +import javax.persistence.Temporal; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.MetadataProcessor; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.validator.EntityValidator; + +/** + * The Class AbstractEntityFieldProcessor. + * + * @author animesh.kumar + */ +public abstract class AbstractEntityFieldProcessor implements MetadataProcessor +{ + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(AbstractEntityFieldProcessor.class); + + /** The Validator. */ + protected EntityValidator validator; + + /** + * Gets the valid jpa column. + * + * @param clazz + * the clazz + * @return the valid jpa column + * @throws PersistenceException + * the persistence exception + */ + + /** + * Validate. + * + * @param clazz + * the clazz + * + * @throws PersistenceException + * the persistence exception + */ + public final void validate(Class clazz) throws PersistenceException + { + validator.validate(clazz); + } + + /** + * Gets the valid jpa column name. + * + * @param entity + * the entity + * @param f + * the f + * @return the valid jpa column name + */ + protected final String getValidJPAColumnName(Class entity, Field f) + { + + String name = null; + + if (f.isAnnotationPresent(Column.class)) + { + Column c = f.getAnnotation(Column.class); + if (!c.name().isEmpty()) + { + name = c.name(); + } + else + { + name = f.getName(); + } + } + else if (f.isAnnotationPresent(Basic.class)) + { + name = f.getName(); + } + + if (f.isAnnotationPresent(Temporal.class)) + { + if (!f.getType().equals(Date.class)) + { + log.error("@Temporal must map to java.util.Date for @Entity(" + entity.getName() + "." + f.getName() + + ")"); + return name; + } + if (null == name) + { + name = f.getName(); + } + } + return name; + } + + /** + * Populates @Id accesser methods like, getId and setId of clazz to + * metadata. + * + * @param metadata + * the metadata + * @param clazz + * the clazz + * @param f + * the f + */ + protected final void populateIdAccessorMethods(EntityMetadata metadata, Class clazz, Field f) + { + try + { + BeanInfo info = Introspector.getBeanInfo(clazz); + + for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) + { + if (descriptor.getName().equals(f.getName())) + { + metadata.setReadIdentifierMethod(descriptor.getReadMethod()); + metadata.setWriteIdentifierMethod(descriptor.getWriteMethod()); + return; + } + } + } + catch (IntrospectionException e) + { + throw new RuntimeException(e); + } + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/CacheableAnnotationProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/CacheableAnnotationProcessor.java new file mode 100644 index 000000000..939acb3a5 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/CacheableAnnotationProcessor.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import javax.persistence.Cacheable; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.MetadataProcessor; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The MetadataProcessor implementation to scan for EntityListener class/method + * JPA Specifications: 1. EntityListeners classes must have a no-argument + * constructor. 2. Callback methods can have any visibility. 3. Callback methods + * must return void. 4. Callback methods must NOT throw any checked exception. + * 5. ExternalCallback methods must accept only entity object. 6. + * InternalCallback methods must NOT accept any parameter. 7. EntityListeners + * are state-less. 8. EnternalCallbackMethods must be fired before + * InternalCallbackMethods. + * + * @author animesh.kumar + */ + +public class CacheableAnnotationProcessor implements MetadataProcessor +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(CacheableAnnotationProcessor.class); + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.MetadataProcessor#process(java.lang.Class, + * com.impetus.kundera.metadata.model.EntityMetadata) + */ + @Override + public final void process(final Class entityClass, EntityMetadata metadata) + { + + Cacheable cacheable = (Cacheable) entityClass.getAnnotation(Cacheable.class); + + if (null != cacheable) + { + metadata.setCacheable(cacheable.value()); + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/EntityListenersProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/EntityListenersProcessor.java new file mode 100644 index 000000000..0bbdfc303 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/EntityListenersProcessor.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityListeners; +import javax.persistence.PostLoad; +import javax.persistence.PostPersist; +import javax.persistence.PostRemove; +import javax.persistence.PostUpdate; +import javax.persistence.PrePersist; +import javax.persistence.PreRemove; +import javax.persistence.PreUpdate; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.MetadataProcessor; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.event.CallbackMethod; +import com.impetus.kundera.persistence.event.ExternalCallbackMethod; +import com.impetus.kundera.persistence.event.InternalCallbackMethod; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * The MetadataProcessor implementation to scan for EntityListener class/method + * JPA Specifications: 1. EntityListeners classes must have a no-argument + * constructor. 2. Callback methods can have any visibility. 3. Callback methods + * must return void. 4. Callback methods must NOT throw any checked exception. + * 5. ExternalCallback methods must accept only entity object. 6. + * InternalCallback methods must NOT accept any parameter. 7. EntityListeners + * are state-less. 8. EnternalCallbackMethods must be fired before + * InternalCallbackMethods. + * + * @author animesh.kumar + */ + +public class EntityListenersProcessor implements MetadataProcessor +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(EntityListenersProcessor.class); + + // list of all valid JPA Entity Listeners + /** The Constant JPAListenersAnnotations. */ + @SuppressWarnings("unchecked") + private static final List> JPAListenersAnnotations = Arrays.asList(PrePersist.class, + PostPersist.class, PreUpdate.class, PostUpdate.class, PreRemove.class, PostRemove.class, PostLoad.class); + + @Override + public final void process(final Class entityClass, EntityMetadata metadata) + { + + // list all external listeners first. + EntityListeners entityListeners = (EntityListeners) entityClass.getAnnotation(EntityListeners.class); + if (entityListeners != null) + { + Class[] entityListenerClasses = entityListeners.value(); + if (entityListenerClasses != null) + { + // iterate through all EntityListeners + for (Class entityListener : entityListenerClasses) + { + + // entityListener class must have a no-argument constructor + try + { + entityListener.getConstructor(); + } + catch (NoSuchMethodException nsme) + { + throw new MetamodelLoaderException("Skipped method(" + entityListener.getName() + + ") must have a default no-argument constructor."); + } + + // iterate through all public methods + for (Method method : entityListener.getDeclaredMethods()) + { + + // find valid jpa annotations for this method + List> jpaAnnotations = getValidJPAAnnotationsFromMethod(entityListener, method, 1, + entityClass); + + // add them all to metadata + for (Class jpaAnnotation : jpaAnnotations) + { + CallbackMethod callBackMethod = new ExternalCallbackMethod(entityListener, method); + addCallBackMethod(metadata, jpaAnnotation, callBackMethod); + } + } + } + } + } + + // list all internal listeners now. + // iterate through all public methods of entityClass + // since this is already an @Entity class, it will sure have a default + // no-arg constructor + for (Method method : entityClass.getDeclaredMethods()) + { + // find valid jpa annotations for this method + List> jpaAnnotations = getValidJPAAnnotationsFromMethod(entityClass, method, 0, entityClass); + // add them all to metadata + for (Class jpaAnnotation : jpaAnnotations) + { + CallbackMethod callbackMethod = new InternalCallbackMethod(metadata, method); + addCallBackMethod(metadata, jpaAnnotation, callbackMethod); + } + } + } + + /** + * Adds the call back method. + * + * @param metadata + * the metadata + * @param jpaAnnotation + * the jpa annotation + * @param callbackMethod + * the callback method + */ + @SuppressWarnings("unchecked") + private void addCallBackMethod(EntityMetadata metadata, Class jpaAnnotation, CallbackMethod callbackMethod) + { + Map, List> callBackMethodsMap = metadata.getCallbackMethodsMap(); + List list = (List) callBackMethodsMap.get(jpaAnnotation); + if (null == list) + { + list = new ArrayList(); + callBackMethodsMap.put(jpaAnnotation, list); + } + list.add(callbackMethod); + } + + /** + * Gets the valid jpa annotations from method. + * + * @param clazz + * the clazz + * @param method + * the method + * @param numberOfParams + * the number of params + * + * @return the valid jpa annotations from method + */ + private List> getValidJPAAnnotationsFromMethod(Class clazz, Method method, int numberOfParams, + Class entityClazz) + { + List> annotations = new ArrayList>(); + + for (Annotation methodAnnotation : method.getAnnotations()) + { + Class methodAnnotationType = methodAnnotation.annotationType(); + + if (isValidJPAEntityListenerAnnotation(methodAnnotationType)) + { + + // verify method signature + + // verify exceptions + boolean hasUncheckedExceptions = false; + for (Class exception : method.getExceptionTypes()) + { + if (!ReflectUtils.hasSuperClass(RuntimeException.class, exception)) + { + hasUncheckedExceptions = true; + break; + } + } + + if (hasUncheckedExceptions) + { + log.info("Skipped method(" + clazz.getName() + "." + method.getName() + + ") Must not throw unchecked exceptions."); + continue; + } + + // return type must be "void" + if (!method.getReturnType().getSimpleName().equals("void")) + { + log.info("Skipped method(" + clazz.getName() + "." + method.getName() + + ") Must have \"void\" return type."); + continue; + } + // argument must be an Entity or Object + Class[] paramTypes = method.getParameterTypes(); + if (paramTypes.length != numberOfParams) + { + log.info("Skipped method(" + clazz.getName() + "." + method.getName() + ") Must have " + + numberOfParams + " parameter."); + continue; + } + + if (numberOfParams == 1) + { + Class parameter = paramTypes[0]; + if (!(parameter != null && parameter.isAssignableFrom(entityClazz))) + { + log.info("Skipped method(" + clazz.getName() + "." + method.getName() + + ") Must have only 1 \"Object\" type parameter."); + continue; + } + } + + annotations.add(methodAnnotationType); + } + } + return annotations; + } + + /** + * Checks if is valid jpa entity listener annotation. + * + * @param annotation + * the annotation + * + * @return true, if is valid jpa entity listener annotation + */ + private boolean isValidJPAEntityListenerAnnotation(Class annotation) + { + return JPAListenersAnnotations.contains(annotation); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/GeneratedValueProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/GeneratedValueProcessor.java new file mode 100644 index 000000000..af48852a6 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/GeneratedValueProcessor.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.lang.reflect.Field; +import java.util.Map; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.SequenceGenerator; +import javax.persistence.TableGenerator; + +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.IdDiscriptor; +import com.impetus.kundera.metadata.model.SequenceGeneratorDiscriptor; +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; + +public class GeneratedValueProcessor +{ + public void process(Class clazz, Field idField, EntityMetadata m, + Map entityNameToKeyDiscriptorMap) + { + IdDiscriptor keyValue = new IdDiscriptor(); + + GeneratedValue value = idField.getAnnotation(GeneratedValue.class); + String generatorName = value.generator(); + GenerationType generationType = value.strategy(); + + switch (generationType) + { + case TABLE: + TableGeneratorDiscriptor tgd = processTableGenerator(clazz, idField, m, generatorName); + keyValue.setTableDiscriptor(tgd); + keyValue.setStrategy(GenerationType.TABLE); + break; + case SEQUENCE: + SequenceGeneratorDiscriptor sgd = processSequenceGenerator(clazz, idField, m, generatorName); + keyValue.setSequenceDiscriptor(sgd); + keyValue.setStrategy(GenerationType.SEQUENCE); + break; + case IDENTITY: + keyValue.setStrategy(GenerationType.IDENTITY); + break; + case AUTO: + // No need of Any Generator + keyValue.setStrategy(GenerationType.AUTO); + break; + } + entityNameToKeyDiscriptorMap.put(clazz.getName(), keyValue); + } + + private SequenceGeneratorDiscriptor processSequenceGenerator(Class clazz, Field idField, EntityMetadata m, + String generatorName) + { + SequenceGeneratorDiscriptor sgd = null; + if (!generatorName.isEmpty()) + { + SequenceGenerator sequenceGenerator = idField.getAnnotation(SequenceGenerator.class); + if (sequenceGenerator == null || !sequenceGenerator.name().equals(generatorName)) + { + sequenceGenerator = clazz.getAnnotation(SequenceGenerator.class); + } + sgd = new SequenceGeneratorDiscriptor(sequenceGenerator, m.getSchema()); + } + else + { + sgd = new SequenceGeneratorDiscriptor(m.getSchema()); + } + return sgd; + } + + private TableGeneratorDiscriptor processTableGenerator(Class clazz, Field idField, EntityMetadata m, + String generatorName) + { + TableGeneratorDiscriptor tgd = null; + if (!generatorName.isEmpty()) + { + TableGenerator tableGenerator = idField.getAnnotation(TableGenerator.class); + if (tableGenerator == null || !tableGenerator.name().equals(generatorName)) + { + tableGenerator = clazz.getAnnotation(TableGenerator.class); + } + tgd = new TableGeneratorDiscriptor(tableGenerator, m.getSchema(), m.getTableName()); + } + else + { + tgd = new TableGeneratorDiscriptor(m.getSchema(), m.getTableName()); + } + return tgd; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/IndexProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/IndexProcessor.java new file mode 100644 index 000000000..7c504f733 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/IndexProcessor.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EntityType; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.annotations.Index; +import com.impetus.kundera.index.IndexCollection; +import com.impetus.kundera.metadata.MetadataProcessor; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PropertyIndex; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; + +/** + * The Class BaseMetadataProcessor. + * + * @author animesh.kumar + */ +public class IndexProcessor implements MetadataProcessor +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(IndexProcessor.class); + + public final void process(final Class clazz, EntityMetadata metadata) + { + if (clazz != null) + { + metadata.setIndexName(clazz.getSimpleName()); + } + Index idx = clazz.getAnnotation(Index.class); + IndexCollection indexes = clazz.getAnnotation(IndexCollection.class); + + List columnsNameToBeIndexed = new ArrayList(); + + Map indexedColumnsMap = new HashMap(); + + if (null != indexes) + { + if (indexes.columns() != null && indexes.columns().length != 0) + { + metadata.setIndexable(true); + + for (com.impetus.kundera.index.Index indexedColumn : indexes.columns()) + { + indexedColumnsMap.put(indexedColumn.name(), indexedColumn); + } + } + } + else if (null != idx) + { + boolean isIndexable = idx.index(); + + if (isIndexable) + { + metadata.setIndexable(isIndexable); + + String indexName = idx.name(); + if (indexName != null && !indexName.isEmpty()) + { + metadata.setIndexName(indexName); + } + + if (idx.columns() != null && idx.columns().length != 0) + { + for (String indexedColumn : idx.columns()) + { + columnsNameToBeIndexed.add(indexedColumn); + } + } + } + } + else + { + log.debug("@Entity " + clazz.getName() + " will not be indexed for " + + (indexedColumnsMap.isEmpty() ? "all columns" : indexedColumnsMap)); + return; + } + + log.debug("Processing @Entity " + clazz.getName() + " for Indexes."); + + // scan for fields + + EntityType entityType = (EntityType) KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetaModelBuilder(metadata.getPersistenceUnit()).getManagedTypes().get(clazz); + + Set attributes = entityType.getAttributes(); + for (Attribute attrib : attributes) + { + if (!attrib.isAssociation()) + { + String colName = attrib.getName(); + if (indexedColumnsMap != null && !indexedColumnsMap.isEmpty() && indexedColumnsMap.containsKey(colName)) + { + com.impetus.kundera.index.Index indexedColumn = indexedColumnsMap.get(colName); + metadata.addIndexProperty(populatePropertyIndex(((AbstractAttribute) attrib).getJPAColumnName(), + indexedColumn.type(), indexedColumn.max(), indexedColumn.min(), + (Field) attrib.getJavaMember())); + + } + else if (columnsNameToBeIndexed != null && !columnsNameToBeIndexed.isEmpty() + && columnsNameToBeIndexed.contains(colName)) + { + metadata.addIndexProperty(populatePropertyIndex(((AbstractAttribute) attrib).getJPAColumnName(), + null, null, null, (Field) attrib.getJavaMember())); + } + } + + } + /* + * for (Field f : clazz.getDeclaredFields()) { if + * (f.isAnnotationPresent(Column.class)) { String fieldName = + * f.getName(); String colName = getIndexName(f, fieldName); if + * (indexedColumnsMap != null && !indexedColumnsMap.isEmpty() && + * indexedColumnsMap.containsKey(fieldName)) { + * com.impetus.kundera.index.Index indexedColumn = + * indexedColumnsMap.get(fieldName); + * metadata.addIndexProperty(populatePropertyIndex(indexedColumn.name(), + * indexedColumn.type(), indexedColumn.max(), indexedColumn.min(), f)); + * } else if (columnsNameToBeIndexed != null && + * !columnsNameToBeIndexed.isEmpty() && + * columnsNameToBeIndexed.contains(colName)) { + * metadata.addIndexProperty(populatePropertyIndex(fieldName, null, + * null, null, f)); } } } + */ + } + + /** + * @param indexedColumn + * @param f + * @return TODO: Make this method accept n number of parameters elegantly + */ + private static PropertyIndex populatePropertyIndex(String columnName, String indexType, Integer max, Integer min, + Field f) + { + PropertyIndex pi = new PropertyIndex(); + + pi.setProperty(f); + pi.setName(columnName); + pi.setIndexType(indexType); + pi.setMax(max); + pi.setMin(min); + + return pi; + } + + /** + * Returns list of indexed columns on {@code @Embeddable} entity + * + * @param entityMetadata + * entity metadata + * @return list of indexed columns + */ + public static Map getIndexesOnEmbeddable(Class entityClazz) + { + Map pis = new HashMap(); + Index idx = entityClazz.getAnnotation(Index.class); + IndexCollection indexes = entityClazz.getAnnotation(IndexCollection.class); + List columnsNameToBeIndexed = null; + Map columnsToBeIndexed = null; + if (null != indexes) + { + columnsToBeIndexed = new HashMap(); + if (indexes.columns() != null && indexes.columns().length != 0) + { + for (com.impetus.kundera.index.Index indexedColumn : indexes.columns()) + { + columnsToBeIndexed.put(indexedColumn.name(), indexedColumn); + } + } + } + if (null != idx) + { + columnsNameToBeIndexed = new ArrayList(); + if (idx.columns() != null && idx.columns().length != 0) + { + for (String indexedColumn : idx.columns()) + { + columnsNameToBeIndexed.add(indexedColumn); + } + } + } + getPropertyIndexes(entityClazz, pis, columnsNameToBeIndexed, columnsToBeIndexed); + return pis; + } + + /** + * @param entityClazz + * @param pis + * @param columnsNameToBeIndexed + * @param columnsToBeIndexed + */ + private static void getPropertyIndexes(Class entityClazz, Map pis, + List columnsNameToBeIndexed, Map columnsToBeIndexed) + { + for (Field f : entityClazz.getDeclaredFields()) + { + if (f.isAnnotationPresent(Column.class)) + { + String fieldName = f.getName(); + if (columnsToBeIndexed != null && !columnsToBeIndexed.isEmpty() + && columnsToBeIndexed.containsKey(fieldName)) + { + com.impetus.kundera.index.Index indexedColumn = columnsToBeIndexed.get(fieldName); + pis.put(indexedColumn.name(), + populatePropertyIndex(indexedColumn.name(), indexedColumn.type(), indexedColumn.max(), + indexedColumn.min(), f)); + } + else if (columnsNameToBeIndexed != null && !columnsNameToBeIndexed.isEmpty() + && columnsNameToBeIndexed.contains(fieldName)) + { + pis.put(fieldName, populatePropertyIndex(fieldName, null, null, null, f)); + } + } + } + } + + /** + * Gets the index name. + * + * @param f + * the f + * @param alias + * the alias + * @return the index name + */ + private String getIndexName(Field f, String alias) + { + if (f.isAnnotationPresent(Column.class)) + { + Column c = f.getAnnotation(Column.class); + alias = c.name().trim(); + if (alias.isEmpty()) + { + alias = f.getName(); + } + } + return alias; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/MetaModelBuilder.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/MetaModelBuilder.java new file mode 100644 index 000000000..1d90d35eb --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/MetaModelBuilder.java @@ -0,0 +1,793 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.TypeVariable; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javassist.Modifier; + +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.IdClass; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.MappedSuperclass; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Transient; +import javax.persistence.metamodel.Attribute.PersistentAttributeType; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.MappedSuperclassType; +import javax.persistence.metamodel.PluralAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.Type; +import javax.persistence.metamodel.Type.PersistenceType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.model.attributes.DefaultCollectionAttribute; +import com.impetus.kundera.metadata.model.attributes.DefaultListAttribute; +import com.impetus.kundera.metadata.model.attributes.DefaultMapAttribute; +import com.impetus.kundera.metadata.model.attributes.DefaultSetAttribute; +import com.impetus.kundera.metadata.model.attributes.DefaultSingularAttribute; +import com.impetus.kundera.metadata.model.type.AbstractIdentifiableType; +import com.impetus.kundera.metadata.model.type.AbstractManagedType; +import com.impetus.kundera.metadata.model.type.DefaultBasicType; +import com.impetus.kundera.metadata.model.type.DefaultEmbeddableType; +import com.impetus.kundera.metadata.model.type.DefaultEntityType; +import com.impetus.kundera.metadata.model.type.DefaultMappedSuperClass; + +/** + * The Class MetaModelBuilder. + * + * @param + * the generic managed type + * @param + * the generic attribute type + * + * TODO : Handle of {@link MappedSuperclass}, {@link IdClass} + * + * @author vivek.mishra + */ +public final class MetaModelBuilder +{ + /** The Constant log. */ + private static final Logger LOG = LoggerFactory.getLogger(MetaModelBuilder.class); + + /** The managed type. */ + private AbstractManagedType managedType; + + /** The managed types. */ + private Map, EntityType> managedTypes = new HashMap, EntityType>(); + + /** The mapped super class types. */ + private Map, ManagedType> mappedSuperClassTypes = new HashMap, ManagedType>(); + + /** The embeddables. */ + private Map, AbstractManagedType> embeddables = new HashMap, AbstractManagedType>(); + + /** + * Process. + * + * @param clazz + * the clazz + */ + public void process(Class clazz) + { + this.managedType = processInternal(clazz, false); + + // TODO: this.managedType has to be removed. + // Need a validation that TypeBuilder class must be same as + // MetaModelBuilder class. + + // TODO::: To handle association cases, need to check from managedType + // only and populate the same. + + } + + /** + * Adds the embeddables. + * + * @param clazz + * the clazz + * @param embeddable + * the embeddable + */ + void addEmbeddables(Class clazz, AbstractManagedType embeddable) + { + embeddables.put(clazz, embeddable); + } + + /** + * Construct. + * + * @param clazz + * the clazz + * @param attribute + * the attribute + */ + void construct(Class clazz, Field attribute) + { + TypeBuilder typeBuilder = new TypeBuilder(attribute); + typeBuilder.build(managedType, attribute.getType()); + } + + /** + * The Class TypeBuilder. + * + * @param + * the generic type + */ + private class TypeBuilder + { + + /** The attribute. */ + private Field attribute; + + /** The persistent attribute type. */ + private PersistentAttributeType persistentAttribType; + + /** + * Instantiates a new type builder. + * + * @param attribute + * the attribute + */ + TypeBuilder(Field attribute) + { + this.attribute = attribute; + } + + /** + * Instantiates a new type builder. + * + * @param attribute + * the attribute + * @param persistentAttribType + * the persistent attrib type + */ + TypeBuilder(Field attribute, PersistentAttributeType persistentAttribType) + { + this.attribute = attribute; + this.persistentAttribType = persistentAttribType; + } + + /** + * Builds the type. + * + * @param + * the generic type + * @param attribType + * the attrib type + * @return the type + */ + Type buildType(Class attribType) + { + // Only in case of Map attribute attribute will be null; + PersistentAttributeType attributeType = attribute != null ? MetaModelBuilder + .getPersistentAttributeType(attribute) : persistentAttribType; + switch (attributeType) + { + case BASIC: + return new DefaultBasicType(attribType); + case EMBEDDED: + return processOnEmbeddables(attribType); + + case ELEMENT_COLLECTION: + if (attribute != null && Collection.class.isAssignableFrom(attribType)) + { + java.lang.reflect.Type[] argument = ((ParameterizedType) attribute.getGenericType()) + .getActualTypeArguments(); + + return processOnEmbeddables(getTypedClass(argument[0])); + } + else if(attribute != null && Map.class.isAssignableFrom(attribType)) + { + java.lang.reflect.Type[] argument = ((ParameterizedType) attribute.getGenericType()) + .getActualTypeArguments(); + processOnEmbeddables(getTypedClass(argument[0])); + return processOnEmbeddables(getTypedClass(argument[1])); + } + else + { + LOG.warn("Cannot process for : " + attribute + + " as it is not a collection but annotated with @ElementCollection"); + } + default: + if (!(managedTypes.get(attribType) != null)) + { + // get Generic type from attribute and then pass it. + if (attribute != null && isPluralAttribute(attribute)) + { + java.lang.reflect.Type[] arguments = ((ParameterizedType) attribute.getGenericType()) + .getActualTypeArguments(); + if (arguments != null && arguments.length == 1) + { + attribType = (Class) getTypedClass(arguments[0]); + } + else if (arguments != null && arguments.length > 1) + { + attribType = (Class) getTypedClass(arguments[1]); + } + } + + // If generic typed class is managed entity. + if (managedTypes.get(attribType) == null) + { + + if (attribType.isAnnotationPresent(Entity.class)) + { + EntityType entityType = new DefaultEntityType((Class) attribType, + PersistenceType.ENTITY, null); + managedTypes.put(attribType, entityType); + } + else + { + return new DefaultBasicType(attribType); + } + } + } + return (Type) managedTypes.get(attribType); + } + } + + /** + * Process on embeddables. + * + * @param + * the generic type + * @param attribType + * the attrib type + * @return the abstract managed type + */ + private AbstractManagedType processOnEmbeddables(Class attribType) + { + // Check if this embeddable type is already present in + // collection of MetaModelBuider. + AbstractManagedType embeddableType = null; + + PersistenceType persistenceType = PersistenceType.BASIC; + Annotation embeddableAnnotation = attribType.getAnnotation(Embeddable.class); + if(embeddableAnnotation != null) + { + persistenceType = PersistenceType.EMBEDDABLE; + } + + if (!embeddables.containsKey(attribType)) + { + embeddableType = new DefaultEmbeddableType(attribType, persistenceType, null); + + if (attribute != null) + { + Field[] embeddedFields = attribType.getDeclaredFields(); + for (Field f : embeddedFields) + { + if (isNonTransient(f)) + { + new TypeBuilder(f).build(embeddableType, f.getType()); + } + } + } + addEmbeddables(attribType, embeddableType); + } + else + { + embeddableType = (AbstractManagedType) embeddables.get(attribType); + } + + return embeddableType; + } + + /** + * Builds the. + * + * @param managedType + * the managed type + * @param attributeType + * the attribute type + */ + void build(AbstractManagedType managedType, Class attributeType) + { + new AttributeBuilder(attribute, managedType, buildType(attributeType)).build(); + } + + /** + * The Class AttributeBuilder. + * + * @param + * the generic type + * @param + * the generic type + */ + private class AttributeBuilder + { + + /** The attribute. */ + private Field attribute; + + /** The attribute type. */ + private Type attributeType; + + /** The managed type. */ + private AbstractManagedType managedType; + + /** + * Instantiates a new attribute builder. + * + * @param attribute + * the attribute + * @param managedType + * the managed type + * @param attributeType + * the attribute type + */ + public AttributeBuilder(Field attribute, AbstractManagedType managedType, Type attributeType) + { + this.attribute = attribute; + this.managedType = managedType; + this.attributeType = attributeType; + } + + /** + * Builds the. + * + * @param + * the key type + * @param + * the value type + */ + public void build() + { + if (isNonTransient(attribute)) + { + if (isPluralAttribute(attribute)) + { + PluralAttribute pluralAttribute = null; + if (attribute.getType().equals(java.util.Collection.class)) + { + pluralAttribute = new DefaultCollectionAttribute(attributeType, attribute.getName(), + getAttributeType(), managedType, attribute, + (Class>) attribute.getType()); + } + else if (attribute.getType().equals(java.util.List.class)) + { + pluralAttribute = new DefaultListAttribute(attributeType, attribute.getName(), + getAttributeType(), managedType, attribute, (Class>) attribute.getType()); + } + else if (attribute.getType().equals(java.util.Set.class)) + { + pluralAttribute = new DefaultSetAttribute(attributeType, attribute.getName(), + getAttributeType(), managedType, attribute, (Class>) attribute.getType()); + } + else if (attribute.getType().equals(java.util.Map.class)) + { + java.lang.reflect.Type[] arguments = ((ParameterizedType) attribute.getGenericType()) + .getActualTypeArguments(); + + Type keyType = new TypeBuilder(null, getPersistentAttributeType(attribute)) + .buildType(getTypedClass(arguments[0])); + pluralAttribute = new DefaultMapAttribute(attributeType, attribute.getName(), + getAttributeType(), managedType, attribute, (Class>) attribute.getType(), + keyType); + } + ((AbstractManagedType) managedType).addPluralAttribute(attribute.getName(), pluralAttribute); + } + else + { + SingularAttribute singularAttribute = new DefaultSingularAttribute(attribute.getName(), + getAttributeType(), attribute, attributeType, managedType, checkId(attribute)); + ((AbstractManagedType) managedType).addSingularAttribute(attribute.getName(), + singularAttribute); + + if (checkSimpleId(attribute) && checkIdClass(managedType.getJavaType())) + + { + IdClass anno = managedType.getJavaType().getAnnotation(IdClass.class); + AbstractManagedType superType = onSuperType(anno.value(), true); + onDeclaredFields(anno.value(), superType); + ((AbstractIdentifiableType) managedType).addIdAttribute(singularAttribute, true, + superType.getDeclaredSingularAttributes()); + } + else if (checkEmbeddedId(attribute)) + { + AbstractManagedType superType = onSuperType(attribute.getType(), false); + checkEmbeddable(superType.getJavaType(), attribute.getName()); + ((AbstractIdentifiableType) managedType).addIdAttribute(singularAttribute, true, + superType.getDeclaredSingularAttributes()); + + } + else if (checkSimpleId(attribute)) + { + ((AbstractIdentifiableType) managedType).addIdAttribute(singularAttribute, false, null); + } + } + } + } + + /** + * Validates that super type must be embeddable. + * + * @param superType + * @throws MetamodelLoaderException + * exception. + */ + private void checkEmbeddable(Class superType, String fieldname) + { + // check validity. + if (superType != null && !superType.isAnnotationPresent(Embeddable.class)) + { + throw new MetamodelLoaderException("Field: " + fieldname + + " is annotated with @EmbeddedId but corresponding class:" + superType + + " is not an @Embeddable entity"); + } + } + + private AbstractManagedType onSuperType(Class clazz, boolean isIdClass) + { + AbstractManagedType superType = getType(clazz, isIdClass); + + isValidId(superType); + + return superType; + } + + /** + * Check id. + * + * @param member + * the member + * @return true, if successful + */ + boolean checkId(Field member) + { + return checkSimpleId(member) || checkEmbeddedId(member); + } + + /** + * Check simple id. + * + * @param member + * the member + * @return true, if successful + */ + boolean checkSimpleId(Field member) + { + return member.isAnnotationPresent(Id.class); + } + + /** + * Check id class. + * + * @param member + * the member + * @return true, if successful + */ + boolean checkIdClass(Class member) + { + return member.isAnnotationPresent(IdClass.class); + } + + /** + * Check embedded id. + * + * @param member + * the member + * @return true, if successful + */ + boolean checkEmbeddedId(Field member) + { + return member.isAnnotationPresent(EmbeddedId.class); + } + + /** + * Gets the attribute type. + * + * @return the attribute type + */ + PersistentAttributeType getAttributeType() + { + return MetaModelBuilder.getPersistentAttributeType(attribute); + } + } + + private void isValidId(AbstractManagedType superType) + { + if (superType == null) + { + throw new MetamodelLoaderException("field : " + attribute.getName() + + " is either annotated with @EmbeddedId or class:" + managedType.getJavaType() + + " is annotated with @Idclass, but enclosed class is not having any member"); + } + } + + } + + /** + * Gets the managed types. + * + * @return the managedTypes + */ + public Map, EntityType> getManagedTypes() + { + return managedTypes; + } + + /** + * Gets the embeddables. + * + * @return the embeddables + */ + public Map, AbstractManagedType> getEmbeddables() + { + return embeddables; + } + + /** + * @return the mappedSuperClassTypes + */ + public Map, ManagedType> getMappedSuperClassTypes() + { + return mappedSuperClassTypes; + } + + /** + * Returns true, if attribute belongs plural hierarchy. + * + * @param attribute + * the attribute + * @return true, if attribute belongs plural hierarchy. else false. + */ + private boolean isPluralAttribute(Field attribute) + { + return attribute.getType().equals(Collection.class) || attribute.getType().equals(Set.class) + || attribute.getType().equals(List.class) || attribute.getType().equals(Map.class); + } + + /** + * Gets the typed class. + * + * @param type + * the type + * @return the typed class + */ + private Class getTypedClass(java.lang.reflect.Type type) + { + if (type instanceof Class) + { + return ((Class) type); + } + else if (type instanceof ParameterizedType) + { + java.lang.reflect.Type rawParamterizedType = ((ParameterizedType) type).getRawType(); + return getTypedClass(rawParamterizedType); + } + else if (type instanceof TypeVariable) + { + java.lang.reflect.Type upperBound = ((TypeVariable) type).getBounds()[0]; + return getTypedClass(upperBound); + } + + throw new IllegalArgumentException("Error while finding generic class for :" + type); + } + + /** + * Gets the persistent attribute type. + * + * @param member + * the member + * @return the persistent attribute type + */ + static PersistentAttributeType getPersistentAttributeType(Field member) + { + PersistentAttributeType attributeType = PersistentAttributeType.BASIC; + if (member.isAnnotationPresent(ElementCollection.class)) + { + attributeType = PersistentAttributeType.ELEMENT_COLLECTION; + } + else if (member.isAnnotationPresent(OneToMany.class)) + { + attributeType = PersistentAttributeType.ONE_TO_MANY; + } + else if (member.isAnnotationPresent(ManyToMany.class)) + { + attributeType = PersistentAttributeType.MANY_TO_MANY; + } + else if (member.isAnnotationPresent(ManyToOne.class)) + { + attributeType = PersistentAttributeType.MANY_TO_ONE; + } + else if (member.isAnnotationPresent(OneToOne.class)) + { + attributeType = PersistentAttributeType.ONE_TO_ONE; + } + else if (member.isAnnotationPresent(Embedded.class)) + { + attributeType = PersistentAttributeType.EMBEDDED; + } + + return attributeType; + + } + + /** + * Builds the managed type. + * + * @param + * the generic type + * @param clazz + * the clazz + * @return the abstract managed type + */ + private AbstractManagedType buildManagedType(Class clazz, boolean isIdClass) + { + AbstractManagedType managedType = null; + if (clazz.isAnnotationPresent(Embeddable.class)) + { + + validate(clazz, true); + if (!embeddables.containsKey(clazz)) + { + managedType = new DefaultEmbeddableType(clazz, PersistenceType.EMBEDDABLE, getType( + clazz.getSuperclass(), isIdClass)); + onDeclaredFields(clazz, managedType); + embeddables.put(clazz, managedType); + } + else + { + managedType = (AbstractManagedType) embeddables.get(clazz); + } + + } + else if (clazz.isAnnotationPresent(MappedSuperclass.class)) + { + + validate(clazz, false); + if (!mappedSuperClassTypes.containsKey(clazz)) + { + managedType = new DefaultMappedSuperClass(clazz, PersistenceType.MAPPED_SUPERCLASS, + (AbstractIdentifiableType) getType(clazz.getSuperclass(), isIdClass)); + onDeclaredFields(clazz, managedType); + mappedSuperClassTypes.put(clazz, (MappedSuperclassType) managedType); + } + else + { + managedType = (AbstractManagedType) mappedSuperClassTypes.get(clazz); + } + } + else if (clazz.isAnnotationPresent(Entity.class) || isIdClass) + { + if (!managedTypes.containsKey(clazz)) + { + managedType = new DefaultEntityType(clazz, PersistenceType.ENTITY, + (AbstractIdentifiableType) getType(clazz.getSuperclass(), isIdClass)); + // in case of @IdClass, it is a temporary managed type. + if (!isIdClass) + { + managedTypes.put(clazz, (EntityType) managedType); + } + } + else + { + managedType = (AbstractManagedType) managedTypes.get(clazz); + } + } + + return managedType; + } + + /** + * Gets the super type. + * + * @param clazz + * the clazz + * @return the super type + */ + private AbstractManagedType getType(Class clazz, boolean isIdClass) + { + if (clazz != null && !clazz.equals(Object.class)) + { + return processInternal(clazz, isIdClass); + } + return null; + } + + /** + * Validate. + * + * @param + * the generic type + * @param clazz + * the clazz + * @param isEmbeddable + * the is embeddable + */ + private void validate(Class clazz, boolean isEmbeddable) + { + final String mappedSuperClazzErrMsg = "Class:" + clazz + + "is annotated with @MappedSuperClass and @Entity not allowed"; + final String embeddableClazzErrMsg = "Class:" + clazz + "is annotated with @Embeddable and @Entity not allowed"; + if (clazz.isAnnotationPresent(Entity.class)) + { + throw new MetamodelLoaderException(isEmbeddable ? embeddableClazzErrMsg : mappedSuperClazzErrMsg); + } + } + + /** + * On declared fields. + * + * @param + * the generic type + * @param clazz + * the clazz + * @param managedType + * the managed type + */ + private void onDeclaredFields(Class clazz, AbstractManagedType managedType) + { + Field[] embeddedFields = clazz.getDeclaredFields(); + for (Field f : embeddedFields) + { + if (isNonTransient(f)) + { + new TypeBuilder(f).build(managedType, f.getType()); + } + } + } + + /** + * Process. + * + * @param clazz + * the clazz + * @return the abstract managed type + */ + private AbstractManagedType processInternal(Class clazz, boolean isIdClass) + { + if (managedTypes.get(clazz) == null) + { + return buildManagedType(clazz, isIdClass); + } + else + { + return (AbstractManagedType) managedTypes.get(clazz); + } + } + + /** + * @return + */ + private boolean isNonTransient(Field attribute) + { + return attribute != null && !Modifier.isStatic(attribute.getModifiers()) + && !Modifier.isTransient(attribute.getModifiers()) && !attribute.isAnnotationPresent(Transient.class); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/TableProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/TableProcessor.java new file mode 100644 index 000000000..11e5b649c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/TableProcessor.java @@ -0,0 +1,301 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import javassist.Modifier; + +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Embedded; +import javax.persistence.NamedNativeQueries; +import javax.persistence.NamedNativeQuery; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.PersistenceException; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.SingularAttribute; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata.Type; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.processor.relation.RelationMetadataProcessor; +import com.impetus.kundera.metadata.processor.relation.RelationMetadataProcessorFactory; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Metadata processor class for persistent entities. + * + * @author amresh.singh + */ +public class TableProcessor extends AbstractEntityFieldProcessor +{ + + /** The Constant log. */ + private static final Logger LOG = LoggerFactory.getLogger(TableProcessor.class); + + /** holds pu prperties */ + private Map puProperties; + + /** + * Instantiates a new table processor. + */ + public TableProcessor(Map puProperty) + { + validator = new EntityValidatorImpl(puProperty); + this.puProperties = puProperty; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.MetadataProcessor#process(java.lang.Class, + * com.impetus.kundera.metadata.model.EntityMetadata) + */ + @Override + public void process(Class clazz, EntityMetadata metadata) + { + + if (LOG.isDebugEnabled()) + LOG.debug("Processing @Entity(" + clazz.getName() + ") for Persistence Object."); + populateMetadata(metadata, clazz, puProperties); + } + + /** + * Populate metadata. + * + * @param + * the generic type + * @param + * the generic type + * @param metadata + * the metadata + * @param clazz + * the clazz + */ + private void populateMetadata(EntityMetadata metadata, Class clazz, + Map puProperties) + { + Table table = clazz.getAnnotation(Table.class); + // Set Name of persistence object + metadata.setTableName(table.name()); + // Add named/native query related application metadata. + addNamedNativeQueryMetadata(clazz); + // set schema name and persistence unit name (if provided) + String schemaStr = table.schema(); + + MetadataUtils.setSchemaAndPersistenceUnit(metadata, schemaStr, puProperties); + + // scan for fields + + // process for metamodelImpl + + if (metadata.getPersistenceUnit() != null) + { + MetaModelBuilder metaModelBuilder = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetaModelBuilder(metadata.getPersistenceUnit()); + metaModelBuilder.process(clazz); + + for (Field f : clazz.getDeclaredFields()) + { + if (f != null && !Modifier.isStatic(f.getModifiers()) && !Modifier.isTransient(f.getModifiers()) + && !f.isAnnotationPresent(Transient.class)) + { + // construct metamodel. + metaModelBuilder.construct(clazz, f); + + // on id attribute. + + onIdAttribute(metaModelBuilder, metadata, clazz, f); + + // determine if it is a column family or super column + // family. + + onFamilyType(metadata, clazz, f); + + onJPAColumnMapping(metaModelBuilder, metadata, f); + + /* Scan for Relationship field */ + addRelationIntoMetadata(clazz, f, metadata); + } + } + } + + } + + /** + * Adds relationship info into metadata for a given field + * relationField. + * + * @param entityClass + * the entity class + * @param relationField + * the relation field + * @param metadata + * the metadata + */ + private void addRelationIntoMetadata(Class entityClass, Field relationField, EntityMetadata metadata) + { + RelationMetadataProcessor relProcessor = null; + + try + { + + relProcessor = RelationMetadataProcessorFactory.getRelationMetadataProcessor(relationField); + + if (relProcessor != null) + { + relProcessor.addRelationIntoMetadata(relationField, metadata); + } + + } + catch (PersistenceException pe) + { + throw new MetamodelLoaderException("Error with relationship in @Entity(" + entityClass + "." + + relationField.getName() + "), reason: " + pe); + } + } + + /** + * Add named/native query annotated fields to application meta data. + * + * @param clazz + * entity class. + */ + private void addNamedNativeQueryMetadata(Class clazz) + { + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + String name, query = null; + if (clazz.isAnnotationPresent(NamedQuery.class)) + { + NamedQuery ann = (NamedQuery) clazz.getAnnotation(NamedQuery.class); + appMetadata.addQueryToCollection(ann.name(), ann.query(), false, clazz); + } + + if (clazz.isAnnotationPresent(NamedQueries.class)) + { + NamedQueries ann = (NamedQueries) clazz.getAnnotation(NamedQueries.class); + + NamedQuery[] anns = ann.value(); + for (NamedQuery a : anns) + { + appMetadata.addQueryToCollection(a.name(), a.query(), false, clazz); + } + } + + if (clazz.isAnnotationPresent(NamedNativeQuery.class)) + { + NamedNativeQuery ann = (NamedNativeQuery) clazz.getAnnotation(NamedNativeQuery.class); + appMetadata.addQueryToCollection(ann.name(), ann.query(), true, clazz); + } + + if (clazz.isAnnotationPresent(NamedNativeQueries.class)) + { + NamedNativeQueries ann = (NamedNativeQueries) clazz.getAnnotation(NamedNativeQueries.class); + + NamedNativeQuery[] anns = ann.value(); + for (NamedNativeQuery a : anns) + { + appMetadata.addQueryToCollection(a.name(), a.query(), true, clazz); + } + } + } + + /** + * On id attribute. + * + * @param builder + * the builder + * @param entityMetadata + * the entity metadata + * @param clazz + * the clazz + * @param f + * the f + */ + private void onIdAttribute(final MetaModelBuilder builder, EntityMetadata entityMetadata, final Class clazz, Field f) + { + EntityType entity = (EntityType) builder.getManagedTypes().get(clazz); + Attribute attrib = entity.getAttribute(f.getName()); + if (!attrib.isCollection() && ((SingularAttribute) attrib).isId()) + { + entityMetadata.setIdAttribute((SingularAttribute) attrib); + populateIdAccessorMethods(entityMetadata, clazz, f); + } + } + + /** + * On family type. + * + * @param entityMetadata + * the entity metadata + * @param clazz + * the clazz + * @param f + * the f + */ + private void onFamilyType(EntityMetadata entityMetadata, final Class clazz, Field f) + { + if (entityMetadata.getType() == null || !entityMetadata.getType().equals(Type.SUPER_COLUMN_FAMILY)) + { + if ((f.isAnnotationPresent(Embedded.class) && f.getType().getAnnotation(Embeddable.class) != null)) + { + entityMetadata.setType(Type.SUPER_COLUMN_FAMILY); + } + else if (f.isAnnotationPresent(ElementCollection.class) && !MetadataUtils.isBasicElementCollectionField(f)) + { + entityMetadata.setType(Type.SUPER_COLUMN_FAMILY); + } + else + { + entityMetadata.setType(Type.COLUMN_FAMILY); + } + } + } + + /** + * On jpa column mapping. + * + * @param builder + * the builder + * @param entityMetadata + * the entity metadata + * @param f + * the f + */ + private void onJPAColumnMapping(final MetaModelBuilder builder, EntityMetadata entityMetadata, Field f) + { + EntityType entityType = (EntityType) builder.getManagedTypes().get(entityMetadata.getEntityClazz()); + AbstractAttribute attribute = (AbstractAttribute) entityType.getAttribute(f.getName()); + entityMetadata.addJPAColumnMapping(attribute.getJPAColumnName(), f.getName()); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToManyRelationMetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToManyRelationMetadataProcessor.java new file mode 100644 index 000000000..4b81d80be --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToManyRelationMetadataProcessor.java @@ -0,0 +1,192 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.MapKeyClass; +import javax.persistence.MapKeyJoinColumn; + +import org.apache.commons.lang.StringUtils; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.processor.AbstractEntityFieldProcessor; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.metadata.validator.InvalidEntityDefinitionException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * The Class ManyToManyRelationMetadataProcessor. + * + * @author Amresh Singh + */ +public class ManyToManyRelationMetadataProcessor extends AbstractEntityFieldProcessor implements + RelationMetadataProcessor +{ + + /** + * Instantiates a new many to many relation metadata processor. + */ + public ManyToManyRelationMetadataProcessor() + { + validator = new EntityValidatorImpl(); + } + + @Override + public void addRelationIntoMetadata(Field relationField, EntityMetadata metadata) + { + ManyToMany m2mAnnotation = relationField.getAnnotation(ManyToMany.class); + + boolean isJoinedByFK = relationField.isAnnotationPresent(JoinColumn.class); + boolean isJoinedByTable = relationField.isAnnotationPresent(JoinTable.class); + boolean isJoinedByMap = false; + if (m2mAnnotation != null && relationField.getType().isAssignableFrom(Map.class)) + { + /* + * if(! relationField.isAnnotationPresent(MapKeyJoinColumn.class)) { + * throw new InvalidEntityDefinitionException( + * "All @ManyToMany relationship whose field type is Map, must be annotated with @MapKeyJoinColumn" + * ); } + */ + isJoinedByMap = true; + } + + Class targetEntity = null; + Class mapKeyClass = null; + + if (!isJoinedByMap) + { + + targetEntity = PropertyAccessorHelper.getGenericClass(relationField); + } + else + { + List> genericClasses = PropertyAccessorHelper.getGenericClasses(relationField); + + if (!genericClasses.isEmpty() && genericClasses.size() == 2) + { + mapKeyClass = genericClasses.get(0); + targetEntity = genericClasses.get(1); + } + + MapKeyClass mapKeyClassAnn = relationField.getAnnotation(MapKeyClass.class); + + // Check for Map key class specified at annotation + if (mapKeyClass == null && mapKeyClassAnn != null && mapKeyClassAnn.value() != null + && !mapKeyClassAnn.value().getSimpleName().equals("void")) + { + mapKeyClass = mapKeyClassAnn.value(); + } + + if (mapKeyClass == null) + { + throw new InvalidEntityDefinitionException( + "For a Map relationship field," + + " it is mandatory to specify Map key class either using @MapKeyClass annotation or through generics"); + } + + } + + // Check for target class specified at annotation + if (targetEntity == null && null != m2mAnnotation.targetEntity() + && !m2mAnnotation.targetEntity().getSimpleName().equals("void")) + { + targetEntity = m2mAnnotation.targetEntity(); + } + + if (targetEntity == null) + { + throw new InvalidEntityDefinitionException("Could not determine target entity class for relationship." + + " It should either be specified using targetEntity attribute of @ManyToMany or through generics"); + } + + validate(targetEntity); + Relation relation = new Relation(relationField, targetEntity, relationField.getType(), m2mAnnotation.fetch(), + Arrays.asList(m2mAnnotation.cascade()), Boolean.TRUE, m2mAnnotation.mappedBy(), + Relation.ForeignKey.MANY_TO_MANY); + + if (isJoinedByFK) + { + throw new InvalidEntityDefinitionException( + "@JoinColumn not allowed for ManyToMany relationship. Use @JoinTable instead"); + + } + + if (isJoinedByTable) + { + JoinTableMetadata jtMetadata = new JoinTableMetadata(relationField); + + relation.setRelatedViaJoinTable(true); + relation.setJoinTableMetadata(jtMetadata); + } + + if (isJoinedByMap) + { + relation.setMapKeyJoinClass(mapKeyClass); + + MapKeyJoinColumn mapKeyJoinColumnAnn = relationField.getAnnotation(MapKeyJoinColumn.class); + if (mapKeyJoinColumnAnn != null) + { + String mapKeyJoinColumnName = mapKeyJoinColumnAnn.name(); + if (!StringUtils.isEmpty(mapKeyJoinColumnName)) + { + relation.setJoinColumnName(mapKeyJoinColumnName); + } + else + { + throw new InvalidEntityDefinitionException( + "It's mandatory to specify name attribute with @MapKeyJoinColumn annotation"); + } + } + + } + + else if (!isJoinedByTable && !isJoinedByMap + && (relation.getMappedBy() == null || relation.getMappedBy().isEmpty())) + { + throw new InvalidEntityDefinitionException( + "It's manadatory to use @JoinTable with parent side of ManyToMany relationship."); + } + + relation.setBiDirectionalField(metadata.getEntityClazz()); + metadata.addRelation(relationField.getName(), relation); + + // Set whether this entity has at least one Join table relation, if not + // already set + if (!metadata.isRelationViaJoinTable()) + { + metadata.setRelationViaJoinTable(relation.isRelatedViaJoinTable()); + } + + + } + + @Override + public void process(Class clazz, EntityMetadata metadata) + { + throw new MetamodelLoaderException("Method call not applicable for Relation processors"); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToOneRelationMetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToOneRelationMetadataProcessor.java new file mode 100644 index 000000000..34b172e70 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/ManyToOneRelationMetadataProcessor.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; +import java.util.Arrays; + +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToOne; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.processor.AbstractEntityFieldProcessor; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; + +/** + * The Class ManyToOneRelationMetadataProcessor. + * + * @author Amresh Singh + */ +public class ManyToOneRelationMetadataProcessor extends AbstractEntityFieldProcessor implements + RelationMetadataProcessor +{ + + /** + * Instantiates a new many to one relation metadata processor. + */ + public ManyToOneRelationMetadataProcessor() + { + validator = new EntityValidatorImpl(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.metadata.processor.relation.RelationMetadataProcessor + * #addRelationIntoMetadata(java.lang.reflect.Field, + * com.impetus.kundera.metadata.model.EntityMetadata) + */ + @Override + public void addRelationIntoMetadata(Field relationField, EntityMetadata metadata) + { + // taking field's type as foreign entity, ignoring "targetEntity" + Class targetEntity = relationField.getType(); + + validate(targetEntity); + + ManyToOne ann = relationField.getAnnotation(ManyToOne.class); + + Relation relation = new Relation(relationField, targetEntity, null, ann.fetch(), Arrays.asList(ann.cascade()), + ann.optional(), null, // mappedBy is + // null + Relation.ForeignKey.MANY_TO_ONE); + + boolean isJoinedByFK = relationField.isAnnotationPresent(JoinColumn.class); + boolean isJoinedByTable = relationField.isAnnotationPresent(JoinTable.class); + + if (isJoinedByFK) + { + JoinColumn joinColumnAnn = relationField.getAnnotation(JoinColumn.class); + relation.setJoinColumnName(joinColumnAnn.name()); + } + else if (isJoinedByTable) + { + throw new UnsupportedOperationException("@JoinTable not supported for many to one association"); +/* + JoinTableMetadata jtMetadata = new JoinTableMetadata(relationField); + + relation.setRelatedViaJoinTable(true); + relation.setJoinTableMetadata(jtMetadata); +*/ } + + relation.setBiDirectionalField(metadata.getEntityClazz()); + metadata.addRelation(relationField.getName(), relation); + + } + + @Override + public void process(Class clazz, EntityMetadata metadata) + { + throw new MetamodelLoaderException("Method call not applicable for Relation processors"); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToManyRelationMetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToManyRelationMetadataProcessor.java new file mode 100644 index 000000000..3c232f568 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToManyRelationMetadataProcessor.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; +import java.util.Arrays; + +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToMany; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.processor.AbstractEntityFieldProcessor; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * The Class OneToManyRelationMetadataProcessor. + * + * @author Amresh Singh + */ +public class OneToManyRelationMetadataProcessor extends AbstractEntityFieldProcessor implements + RelationMetadataProcessor +{ + + /** + * Instantiates a new one to many relation metadata processor. + */ + public OneToManyRelationMetadataProcessor() + { + validator = new EntityValidatorImpl(); + } + + @Override + public void process(Class clazz, EntityMetadata metadata) + { + throw new MetamodelLoaderException("Method call not applicable for Relation processors"); + } + + @Override + public void addRelationIntoMetadata(Field relationField, EntityMetadata metadata) + { + + OneToMany ann = relationField.getAnnotation(OneToMany.class); + Class targetEntity = PropertyAccessorHelper.getGenericClass(relationField); + + // now, check annotations + if (null != ann.targetEntity() && !ann.targetEntity().getSimpleName().equals("void")) + { + targetEntity = ann.targetEntity(); + } + + validate(targetEntity); + + Relation relation = new Relation(relationField, targetEntity, relationField.getType(), ann.fetch(), + Arrays.asList(ann.cascade()), Boolean.TRUE, ann.mappedBy(), Relation.ForeignKey.ONE_TO_MANY); + + boolean isJoinedByFK = relationField.isAnnotationPresent(JoinColumn.class); + boolean isJoinedByTable = relationField.isAnnotationPresent(JoinTable.class); + + if (isJoinedByFK) + { + JoinColumn joinColumnAnn = relationField.getAnnotation(JoinColumn.class); + relation.setJoinColumnName(joinColumnAnn.name()); + } + else if (isJoinedByTable) + { + throw new UnsupportedOperationException("@JoinTable not supported for one to many association"); +/* JoinTableMetadata jtMetadata = new JoinTableMetadata(relationField); + + relation.setRelatedViaJoinTable(true); + relation.setJoinTableMetadata(jtMetadata); +*/ } + else + { + + String joinColumnName = ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName(); + if (relation.getMappedBy() != null) + { + try + { + + Field mappedField = metadata.getEntityClazz().getDeclaredField(relation.getMappedBy()); + if (mappedField != null && mappedField.isAnnotationPresent(JoinColumn.class)) + { + joinColumnName = mappedField.getAnnotation(JoinColumn.class).name(); + } + } + catch (NoSuchFieldException e) + { + // do nothing, it means not a case of self association + } + catch (SecurityException e) + { + // do nothing, it means not a case of self association + } + } + relation.setJoinColumnName(joinColumnName); + } + + relation.setBiDirectionalField(metadata.getEntityClazz()); + metadata.addRelation(relationField.getName(), relation); + metadata.setParent(true); + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToOneRelationMetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToOneRelationMetadataProcessor.java new file mode 100644 index 000000000..d6861d612 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/OneToOneRelationMetadataProcessor.java @@ -0,0 +1,109 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; +import java.util.Arrays; + +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; + +import com.impetus.kundera.loader.MetamodelLoaderException; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.processor.AbstractEntityFieldProcessor; +import com.impetus.kundera.metadata.validator.EntityValidatorImpl; + +/** + * The Class OneToOneRelationMetadataProcessor. + * + * @author Amresh Singh + */ +public class OneToOneRelationMetadataProcessor extends AbstractEntityFieldProcessor implements + RelationMetadataProcessor +{ + + /** + * Instantiates a new one to one relation metadata processor. + */ + public OneToOneRelationMetadataProcessor() + { + validator = new EntityValidatorImpl(); + } + + @Override + public void addRelationIntoMetadata(Field relationField, EntityMetadata metadata) + { + // taking field's type as foreign entity, ignoring "targetEntity" + Class targetEntity = relationField.getType(); + validate(targetEntity); + + // TODO: Add code to check whether this entity has already been + // validated, at all places below + + OneToOne oneToOneAnn = relationField.getAnnotation(OneToOne.class); + + boolean isJoinedByPK = relationField.isAnnotationPresent(PrimaryKeyJoinColumn.class); + boolean isJoinedByFK = relationField.isAnnotationPresent(JoinColumn.class); + boolean isJoinedByTable = relationField.isAnnotationPresent(JoinTable.class); + + /* + * if(!isJoinedByPK && !isJoinedByFK) { throw new PersistenceException( + * "A one-to-one relationship must have either JoinColumn or PrimaryKeyJoinColumn annotation" + * ); } + */ + + Relation relation = new Relation(relationField, targetEntity, null, oneToOneAnn.fetch(), + Arrays.asList(oneToOneAnn.cascade()), oneToOneAnn.optional(), oneToOneAnn.mappedBy(), + Relation.ForeignKey.ONE_TO_ONE); + + if (isJoinedByPK) + { + + relation.setJoinedByPrimaryKey(true); + EntityMetadata joinClassMetadata = KunderaMetadataManager.getEntityMetadata(targetEntity.getClass()); + relation.setJoinColumnName(joinClassMetadata != null? ((AbstractAttribute)joinClassMetadata.getIdAttribute()).getJPAColumnName(): null); + } + else if (isJoinedByFK) + { + JoinColumn joinColumnAnn = relationField.getAnnotation(JoinColumn.class); + relation.setJoinColumnName(joinColumnAnn.name()); + } + else if (isJoinedByTable) + { + throw new UnsupportedOperationException("@JoinTable not supported for one to one association"); +/* JoinTableMetadata jtMetadata = new JoinTableMetadata(relationField); + relation.setRelatedViaJoinTable(true); + relation.setJoinTableMetadata(jtMetadata); +*/ } + + relation.setBiDirectionalField(metadata.getEntityClazz()); + metadata.addRelation(relationField.getName(), relation); + + } + + @Override + public void process(Class clazz, EntityMetadata metadata) + { + throw new MetamodelLoaderException("Method call not applicable for Relation processors"); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessor.java new file mode 100644 index 000000000..d88e5a3f0 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessor.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; + +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The Interface RelationMetadataProcessor. + * + * @author Amresh Singh + */ +public interface RelationMetadataProcessor +{ + + /** + * Adds the relation into metadata. + * + * @param relationField + * the relation field + * @param metadata + * the metadata + */ + void addRelationIntoMetadata(Field relationField, EntityMetadata metadata); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessorFactory.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessorFactory.java new file mode 100644 index 000000000..8bc899cc1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/processor/relation/RelationMetadataProcessorFactory.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.processor.relation; + +import java.lang.reflect.Field; + +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; + +/** + * A factory for creating RelationMetadataProcessor objects. + * + * @author Amresh Singh + */ +public class RelationMetadataProcessorFactory +{ + + /** + * Gets the relation metadata processor. + * + * @param relationField + * the relation field + * @return the relation metadata processor + */ + public static RelationMetadataProcessor getRelationMetadataProcessor(Field relationField) + { + RelationMetadataProcessor relProcessor = null; + + // OneToOne + if (relationField.isAnnotationPresent(OneToOne.class)) + { + relProcessor = new OneToOneRelationMetadataProcessor(); + } + + // OneToMany + else if (relationField.isAnnotationPresent(OneToMany.class)) + { + relProcessor = new OneToManyRelationMetadataProcessor(); + + } + + // ManyToOne + else if (relationField.isAnnotationPresent(ManyToOne.class)) + { + relProcessor = new ManyToOneRelationMetadataProcessor(); + + } + + // ManyToMany + else if (relationField.isAnnotationPresent(ManyToMany.class)) + { + relProcessor = new ManyToManyRelationMetadataProcessor(); + + } + + return relProcessor; + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidator.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidator.java new file mode 100644 index 000000000..f26760aba --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidator.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.validator; + +/** + * Interface to validate an entity. + * + * @author animesh.kumar + */ +public interface EntityValidator +{ + + /** + * Validate. + * + * @param clazz + * the clazz + */ + void validate(Class clazz); + + /** + * Validate entity. + * + * @param clazz + * the clazz + * @param puProperties + */ + void validateEntity(Class clazz); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidatorImpl.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidatorImpl.java new file mode 100644 index 000000000..e6bf9a6a7 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/EntityValidatorImpl.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.validator; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Validates entity for JPA rules. + * + * @author animesh.kumar + */ +public class EntityValidatorImpl implements EntityValidator +{ + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(EntityValidatorImpl.class); + + /** cache for validated classes. */ + private List> classes = new ArrayList>(); + + private Map puProperties; + + /** + * @param puPropertyMap + */ + public EntityValidatorImpl(Map puPropertyMap) + { + this.puProperties = puPropertyMap; + } + + /** + * @param externalPropertyMap + */ + public EntityValidatorImpl() + { + this(null); + } + + /** + * Checks the validity of a class for Cassandra entity. + * + * @param clazz + * validates this class + * + * @return returns 'true' if valid + */ + @Override + // TODO: reduce Cyclomatic complexity + public final void validate(final Class clazz) + { + + if (classes.contains(clazz)) + { + return; + } + + if (log.isDebugEnabled()) + log.debug("Validating " + clazz.getName()); + + // Is Entity? + if (!clazz.isAnnotationPresent(Entity.class)) + { + throw new InvalidEntityDefinitionException(clazz.getName() + " is not annotated with @Entity."); + } + + // Must be annotated with @Table + if (!clazz.isAnnotationPresent(Table.class)) + { + throw new InvalidEntityDefinitionException(clazz.getName() + " must be annotated with @Table."); + } + + // must have a default no-argument constructor + try + { + clazz.getConstructor(); + } + catch (NoSuchMethodException nsme) + { + throw new InvalidEntityDefinitionException(clazz.getName() + + " must have a default no-argument constructor."); + } + + // Check for @Key and ensure that there is just 1 @Key field of String + // type. + List keys = new ArrayList(); + for (Field field : clazz.getDeclaredFields()) + { + if (field.isAnnotationPresent(Id.class) && field.isAnnotationPresent(EmbeddedId.class)) + { + throw new InvalidEntityDefinitionException(clazz.getName() + + " must have either @Id field or @EmbeddedId field"); + } + + if (field.isAnnotationPresent(Id.class)) + { + keys.add(field); + // validate @GeneratedValue annotation if given + if (field.isAnnotationPresent(GeneratedValue.class)) + { + validateGeneratedValueAnnotation(clazz, field); + } + } + else if (field.isAnnotationPresent(EmbeddedId.class)) + { + keys.add(field); + } + } + + if (keys.size() < 0) + { + throw new InvalidEntityDefinitionException(clazz.getName() + " must have an @Id field."); + } + else if (keys.size() > 1) + { + throw new InvalidEntityDefinitionException(clazz.getName() + " can only have 1 @Id field."); + } + + // save in cache + + classes.add(clazz); + } + + /** + * validate generated value annotation if given. + * + * @param clazz + * @param field + */ + private void validateGeneratedValueAnnotation(final Class clazz, Field field) + { + Table table = clazz.getAnnotation(Table.class); + String schemaName = table.schema(); + if (schemaName != null && schemaName.indexOf('@') > 0) + { + schemaName = schemaName.substring(0, schemaName.indexOf('@')); + GeneratedValue generatedValue = field.getAnnotation(GeneratedValue.class); + if (generatedValue != null && generatedValue.generator() != null && !generatedValue.generator().isEmpty()) + { + if (!(field.isAnnotationPresent(TableGenerator.class) + || field.isAnnotationPresent(SequenceGenerator.class) + || clazz.isAnnotationPresent(TableGenerator.class) || clazz + .isAnnotationPresent(SequenceGenerator.class))) + { + log.error("Unknown Id.generator{}: for class{}",generatedValue.generator(),clazz); + throw new IllegalArgumentException("Unknown Id.generator: " + generatedValue.generator()); + } + else + { + checkForGenerator(clazz, field, generatedValue, schemaName); + } + } + } + } + + /** + * Validate for generator. + * + * @param clazz + * @param field + * @param generatedValue + * @param schemaName + */ + private void checkForGenerator(final Class clazz, Field field, GeneratedValue generatedValue, String schemaName) + { + TableGenerator tableGenerator = field.getAnnotation(TableGenerator.class); + SequenceGenerator sequenceGenerator = field.getAnnotation(SequenceGenerator.class); + if (tableGenerator == null || !tableGenerator.name().equals(generatedValue.generator())) + { + tableGenerator = clazz.getAnnotation(TableGenerator.class); + } + if (sequenceGenerator == null || !sequenceGenerator.name().equals(generatedValue.generator())) + { + sequenceGenerator = clazz.getAnnotation(SequenceGenerator.class); + } + + if ((tableGenerator == null && sequenceGenerator == null) + || (tableGenerator != null && !tableGenerator.name().equals(generatedValue.generator())) + || (sequenceGenerator != null && !sequenceGenerator.name().equals(generatedValue.generator()))) + { + throw new IllegalArgumentException("Unknown Id.generator: " + generatedValue.generator()); + } + else if ((tableGenerator != null && !tableGenerator.schema().isEmpty() && !tableGenerator.schema().equals( + schemaName)) + || (sequenceGenerator != null && !sequenceGenerator.schema().isEmpty() && !sequenceGenerator.schema() + .equals(schemaName))) + { + throw new InvalidEntityDefinitionException("Generator " + generatedValue.generator() + " in entity : " + + clazz.getName() + " has different schema name ,it should be same as entity have"); + } + } + + @Override + public void validateEntity(Class clazz) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(clazz); + if (metadata != null) + { + SchemaManager schemaManager = ClientResolver.getClientFactory(metadata.getPersistenceUnit()) + .getSchemaManager(puProperties); + if (schemaManager != null && !schemaManager.validateEntity(clazz)) + { + log.warn("Validation for : " + clazz + " failed , any operation on this class will result in fail."); + } + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/InvalidEntityDefinitionException.java b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/InvalidEntityDefinitionException.java new file mode 100644 index 000000000..2e9287e9d --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/metadata/validator/InvalidEntityDefinitionException.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.metadata.validator; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh + * + */ +public class InvalidEntityDefinitionException extends KunderaException +{ + + /** + * + */ + private static final long serialVersionUID = 944429642343486327L; + + /** + * + */ + public InvalidEntityDefinitionException() + { + + } + + /** + * @param paramString + */ + public InvalidEntityDefinitionException(String paramString) + { + super(paramString); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AbstractEntityReader.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AbstractEntityReader.java new file mode 100644 index 000000000..38470fe3c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AbstractEntityReader.java @@ -0,0 +1,544 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.FetchType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.persistence.context.PersistenceCacheManager; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.proxy.ProxyHelper; + +/** + * The Class AbstractEntityReader. + * + * @author vivek.mishra + */ +public class AbstractEntityReader +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(AbstractEntityReader.class); + + /** The lucene query from jpa query. */ + protected String luceneQueryFromJPAQuery; + + private AssociationBuilder associationBuilder; + + /** + * Retrieves an entity from ID + * + * @param primaryKey + * @param m + * @param client + * @return + */ + protected EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client) + { + try + { + Object o = client.find(m.getEntityClazz(), primaryKey); + + if (o == null) + { + // No entity found + return null; + } + else + { + return o instanceof EnhanceEntity ? (EnhanceEntity) o : new EnhanceEntity(o, getId(o, m), null); + } + } + catch (Exception e) + { + throw new EntityReaderException(e); + } + } + + /** + * Recursively fetches associated entities for a given entity + * + * @param entity + * @param relationsMap + * @param client + * @param m + * @param pd + * @return + */ + private Object handleAssociation(final Object entity, final Map relationsMap, + final EntityMetadata m, final PersistenceDelegator pd, boolean lazilyloaded) + { + + for (Relation relation : m.getRelations()) + { + ForeignKey relationType = relation.getType(); + + Object relationalObject = PropertyAccessorHelper.getObject(entity, relation.getProperty()); + + // TODO: Need to check if object is a collection instance but empty! + if (relationalObject == null || ProxyHelper.isProxyOrCollection(relationalObject)) + { + onRelation(entity, relationsMap, m, pd, relation, relationType, lazilyloaded); + } + } + return entity; + } + + /** + * Parse over each relation of fetched entity. + * + * @param entity + * @param relationsMap + * @param m + * @param pd + * @param relation + * @param relationType + * @param lazilyloaded + */ + private void onRelation(final Object entity, final Map relationsMap, final EntityMetadata m, + final PersistenceDelegator pd, Relation relation, ForeignKey relationType, boolean lazilyloaded) + { + + FetchType fetchType = relation.getFetchType(); + + if (!lazilyloaded && fetchType.equals(FetchType.LAZY)) + { + final Object entityId = PropertyAccessorHelper.getId(entity, m); + getAssociationBuilder().setProxyRelationObject(entity, relationsMap, m, pd, entityId, relation); + } + else + { + if (relation.getType().equals(ForeignKey.MANY_TO_MANY)) + { + // First, Save this entity to persistence cache + Field f = relation.getProperty(); + Object object = PropertyAccessorHelper.getObject(entity, f); + final Object entityId = PropertyAccessorHelper.getId(entity, m); + PersistenceCacheManager.addEntityToPersistenceCache(entity, pd, entityId); + getAssociationBuilder().populateRelationForM2M(entity, m, pd, relation, object, relationsMap); + } + else + { + onRelation(entity, relationsMap, relation, m, pd, lazilyloaded); + } + } + } + + /** + * Method to handle one to one association relation events. + * + * @param entity + * relation owning entity. + * @param entityId + * entity id of relation owning entity. + * @param relationsMap + * contains relation name and it's value. + * @param m + * entity metadata. + */ + private void onRelation(Object entity, Map relationsMap, final Relation relation, + final EntityMetadata metadata, final PersistenceDelegator pd, boolean lazilyloaded) + { + final Object entityId = PropertyAccessorHelper.getId(entity, metadata); + + // if relation map contains value, then invoke target entity with find + // by id. + // else invoke target entity for find by relation, pass it's entityId as + // a column value and relation.getJoinColumnName as column name. + + Object relationValue = relationsMap != null ? relationsMap.get(relation.getJoinColumnName()) : null; + EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation.getTargetEntity()); + + List relationalEntities = fetchRelations(relation, metadata, pd, entityId, relationValue, targetEntityMetadata); + + // parse for associated relation. + + if (relationalEntities != null) + { + for (Object relationEntity : relationalEntities) + { + onParseRelation(entity, pd, targetEntityMetadata, relationEntity, relation, lazilyloaded); + PersistenceCacheManager.addEntityToPersistenceCache(getEntity(relationEntity), pd, + PropertyAccessorHelper.getId(relationEntity, targetEntityMetadata)); + } + } + + } + + /** + * Invokes parseRelations for relation entity and set relational entity within entity + * + * @param entity + * @param pd + * @param targetEntityMetadata + * @param relationEntity + * @param relation + * @param lazilyloaded + */ + private void onParseRelation(Object entity, final PersistenceDelegator pd, EntityMetadata targetEntityMetadata, + Object relationEntity, Relation relation, boolean lazilyloaded) + { + parseRelations(entity, getEntity(relationEntity), getPersistedRelations(relationEntity), pd, + targetEntityMetadata, lazilyloaded); + + // if relation ship is unary, no problem else we need to add + setRelationToEntity(entity, relationEntity, relation); + } + + /** + * After successfully parsing set relational entity object within entity object. + * + * @param entity + * @param relationEntity + * @param relation + */ + private void setRelationToEntity(Object entity, Object relationEntity, Relation relation) + { + if (relation.getTargetEntity().isAssignableFrom(getEntity(relationEntity).getClass())) + { + + if (relation.isUnary()) + { + PropertyAccessorHelper.set(entity, relation.getProperty(), getEntity(relationEntity)); + } + else + { + Object associationObject = PropertyAccessorHelper.getObject(entity, relation.getProperty()); + if (associationObject == null || ProxyHelper.isProxyOrCollection(associationObject)) + { + associationObject = PropertyAccessorHelper.getCollectionInstance(relation.getProperty()); + PropertyAccessorHelper.set(entity, relation.getProperty(), associationObject); + } + + ((Collection) associationObject).add(getEntity(relationEntity)); + } + } + } + + /** + * Parse relations of provided relationEntity. + * + * @param originalEntity + * @param relationEntity + * @param relationsMap + * @param pd + * @param metadata + * @param lazilyloaded + */ + private void parseRelations(final Object originalEntity, final Object relationEntity, + final Map relationsMap, final PersistenceDelegator pd, final EntityMetadata metadata, + boolean lazilyloaded) + { + + for (Relation relation : metadata.getRelations()) + { + + FetchType fetchType = relation.getFetchType(); + + if (!lazilyloaded && fetchType.equals(FetchType.LAZY)) + { + final Object entityId = PropertyAccessorHelper.getId(relationEntity, metadata); + getAssociationBuilder().setProxyRelationObject(relationEntity, relationsMap, metadata, pd, entityId, + relation); + } + else + { + + if (relation.isUnary() && relation.getTargetEntity().isAssignableFrom(originalEntity.getClass())) + { + Object associationObject = PropertyAccessorHelper.getObject(relationEntity, relation.getProperty()); + if (relation.getType().equals(ForeignKey.ONE_TO_ONE)) + { + if ((associationObject == null || ProxyHelper.isProxyOrCollection(associationObject))) + { + PropertyAccessorHelper.set(relationEntity, relation.getProperty(), originalEntity); + } + } + else if (relationsMap != null && relationsMap.containsKey(relation.getJoinColumnName())) + { + PropertyAccessorHelper.set(relationEntity, relation.getProperty(), originalEntity); + } + } + else + { + // Here + // onRelation(relationEntity, relationsMap, metadata, pd, + // relation, relationType); + final Object entityId = PropertyAccessorHelper.getId(relationEntity, metadata); + Object relationValue = relationsMap != null ? relationsMap.get(relation.getJoinColumnName()) : null; + final EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation + .getTargetEntity()); + List immediateRelations = fetchRelations(relation, metadata, pd, entityId, relationValue, + targetEntityMetadata); + // Here in case of one-to-many/many-to-one we should skip + // this + // relation as it + if (immediateRelations != null && !immediateRelations.isEmpty()) + { + // As it + // is + // already + // in process. + + for (Object immediateRelation : immediateRelations) + { + if (!compareTo(getEntity(immediateRelation), originalEntity)) + { + onParseRelation(relationEntity, pd, targetEntityMetadata, immediateRelation, relation, + lazilyloaded); + } + } + setRelationToEntity(relationEntity, originalEntity, relation); + PersistenceCacheManager.addEntityToPersistenceCache(getEntity(relationEntity), pd, + PropertyAccessorHelper.getId(relationEntity, metadata)); + } + } + } + } + } + + /** + * + * Based on relation type, method invokes database to fetch relation entities. + * + * @param relation relation + * @param metadata entity metadata + * @param pd persistence delegator + * @param entityId entity id + * @param relationValue relational value + * @param targetEntityMetadata relational entity's metadata. + * + * @return list of fetched relations. + */ + private List fetchRelations(final Relation relation, final EntityMetadata metadata, final PersistenceDelegator pd, + final Object entityId, Object relationValue, EntityMetadata targetEntityMetadata) + { + List relationalEntities = new ArrayList(); + + if ((relationValue != null && relation.isUnary()) || (relation.isJoinedByPrimaryKey())) + { + // Call it + Object relationEntity = pd.getClient(targetEntityMetadata).find(relation.getTargetEntity(), + relationValue != null ? relationValue : entityId); + if (relationEntity != null) + { + relationalEntities.add(relationEntity); + } + } + else if (!relation.isUnary()) + { + // Now these entities may be enhance entities and may not be as + // well. + Client associatedClient = pd.getClient(targetEntityMetadata); + + if (!MetadataUtils.useSecondryIndex(((ClientBase) associatedClient).getClientMetadata())) + { + + relationalEntities = getAssociationBuilder().getAssociatedEntitiesFromIndex(relation.getProperty() + .getDeclaringClass(), entityId, targetEntityMetadata.getEntityClazz(), associatedClient); + } + else + { + relationalEntities = associatedClient.findByRelation(relation.getJoinColumnName(), entityId, + relation.getTargetEntity()); + } + } + return relationalEntities; + } + + /** + * Recursively fetches associated entities for a given entity + * + * @param entity + * @param relationsMap + * @param client + * @param m + * @param pd + * @return + */ + public Object recursivelyFindEntities(Object entity, Map relationsMap, EntityMetadata m, + PersistenceDelegator pd, boolean lazilyLoaded) + { + return handleAssociation(entity, relationsMap, m, pd, lazilyLoaded); + + } + + /** + * Returns wrapped relations. + * + * @param relationEntity + * @return + */ + private Map getPersistedRelations(Object relationEntity) + { + return relationEntity != null && relationEntity.getClass().isAssignableFrom(EnhanceEntity.class) ? ((EnhanceEntity) relationEntity) + .getRelations() : null; + } + + /** + * Returns wrapped entity. + * + * @param relationEntity + * @return + */ + private Object getEntity(Object relationEntity) + { + return relationEntity.getClass().isAssignableFrom(EnhanceEntity.class) ? ((EnhanceEntity) relationEntity) + .getEntity() : relationEntity; + } + + /** + * On association using lucene. + * + * @param m + * the m + * @param client + * the client + * @param ls + * the ls + * @return the list + */ + protected List onAssociationUsingLucene(EntityMetadata m, Client client, List ls) + { + Set rSet = fetchDataFromLucene(client); + List resultList = client.findAll(m.getEntityClazz(), null, rSet.toArray(new String[] {})); + return m.getRelationNames() != null && !m.getRelationNames().isEmpty() ? resultList : transform(m, ls, + resultList); + } + + /** + * Transform. + * + * @param m + * the m + * @param ls + * the ls + * @param resultList + * the result list + * @return the list + */ + protected List transform(EntityMetadata m, List ls, List resultList) + { + if ((ls == null || ls.isEmpty()) && resultList != null && !resultList.isEmpty()) + { + ls = new ArrayList(resultList.size()); + } + for (Object r : resultList) + { + EnhanceEntity e = new EnhanceEntity(r, getId(r, m), null); + ls.add(e); + } + return ls; + } + + /** + * Fetch data from lucene. + * + * @param client + * the client + * @return the sets the + */ + protected Set fetchDataFromLucene(Client client) + { + // use lucene to query and get Pk's only. + // go to client and get relation with values.! + // populate EnhanceEntity + Map results = client.getIndexManager().search(luceneQueryFromJPAQuery); + Set rSet = new HashSet(results.values()); + return rSet; + } + + /** + * Gets the id. + * + * @param entity + * the entity + * @param metadata + * the metadata + * @return the id + */ + protected Object getId(Object entity, EntityMetadata metadata) + { + try + { + return PropertyAccessorHelper.getId(entity, metadata); + } + catch (PropertyAccessException e) + { + log.error("Error while Getting ID, Caused by: ", e); + throw new EntityReaderException("Error while Getting ID for entity " + entity, e); + } + + } + + /** + * Compares original with relational entity. + * + * @param relationalEntity + * @param originalEntity + * @return + */ + private boolean compareTo(Object relationalEntity, Object originalEntity) + { + if (relationalEntity != null && originalEntity != null + && relationalEntity.getClass().isAssignableFrom(originalEntity.getClass())) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(originalEntity.getClass()); + + Object relationalEntityId = PropertyAccessorHelper.getId(relationalEntity, metadata); + Object originalEntityId = PropertyAccessorHelper.getId(originalEntity, metadata); + + return relationalEntityId.equals(originalEntityId); + } + + return false; + } + + /** + * Returns association builder instance. + * + * @return association builder + */ + private AssociationBuilder getAssociationBuilder() + { + if(this.associationBuilder == null) + { + this.associationBuilder = new AssociationBuilder(); + } + + return this.associationBuilder; + + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AssociationBuilder.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AssociationBuilder.java new file mode 100644 index 000000000..8e9dbc50d --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/AssociationBuilder.java @@ -0,0 +1,441 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.Relation.ForeignKey; +import com.impetus.kundera.persistence.context.PersistenceCacheManager; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.proxy.KunderaProxy; +import com.impetus.kundera.proxy.ProxyHelper; +import com.impetus.kundera.proxy.collection.ProxyCollection; +import com.impetus.kundera.proxy.collection.ProxyList; +import com.impetus.kundera.proxy.collection.ProxyMap; +import com.impetus.kundera.proxy.collection.ProxySet; +import com.impetus.kundera.utils.ObjectUtils; + +/** + * This class is responsible for building association for given entities. + * + * @author vivek.mishra + */ +public final class AssociationBuilder +{ + + private static Logger log = LoggerFactory.getLogger(AssociationBuilder.class); + /** + * Retrieves associated entities from secondary index. There are two + * alternatives here: + * + * 1. Via running Lucene query into Lucene powered secondary index. 2. + * Searching into a secondary index by custom secondary index class provided + * by user. + * + * @see PersistenceProperties#KUNDERA_INDEX_HOME_DIR + * @see PersistenceProperties#KUNDERA_INDEXER_CLASS + * + * TODO: Which secondary index to use should be transparent. All we + * should bother about is indexer.index(), indexer.search() etc. + */ + List getAssociatedEntitiesFromIndex(Class owningClazz, Object entityId, Class childClass, Client childClient) + { + List associatedEntities; + IndexManager indexManager = childClient.getIndexManager(); + + Map results = indexManager != null ? indexManager.search(owningClazz, childClass, entityId) + : new HashMap(); + Set rsSet = results != null ? new HashSet(results.values()) : new HashSet(); + + if (childClass.equals(owningClazz)) + { + associatedEntities = (List) childClient.findAll(childClass, null, rsSet.toArray(new Object[] {})); + } + else + { + associatedEntities = (List) childClient.findAll(childClass, null, rsSet.toArray(new Object[] {})); + } + return associatedEntities; + } + + + /** + * Populates entities related via join table for entity + * + * @param entity + * @param entityMetadata + * @param delegator + * @param relation + */ + void populateRelationForM2M(Object entity, EntityMetadata entityMetadata, PersistenceDelegator delegator, + Relation relation, Object relObject, Map relationsMap) + { + // For M-M relationship of Collection type, relationship entities are + // always fetched from Join Table. + if (relation.getPropertyType().isAssignableFrom(List.class) + || relation.getPropertyType().isAssignableFrom(Set.class)) + { + if (relation.isRelatedViaJoinTable() && (relObject == null || ProxyHelper.isProxyOrCollection(relObject))) + { + populateCollectionFromJoinTable(entity, entityMetadata, delegator, relation); + } + + } + else if (relation.getPropertyType().isAssignableFrom(Map.class)) + { + if (relation.isRelatedViaJoinTable()) + { + // TODO: Implement Map relationships via Join Table (not + // supported as of now) + } + else + { + populateCollectionFromMap(entity, delegator, relation, relObject, relationsMap); + } + } + + } + + /** + * Populates a relationship of type {@link Collection} (i.e. those of type + * {@link Set} or {@link List}) + */ + private void populateCollectionFromJoinTable(Object entity, EntityMetadata entityMetadata, + PersistenceDelegator delegator, Relation relation) + { + JoinTableMetadata jtMetadata = relation.getJoinTableMetadata(); + Client pClient = delegator.getClient(entityMetadata); + + String schema = entityMetadata.getSchema(); + + EntityMetadata owningEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation.getTargetEntity()); + Class columnJavaType = owningEntityMetadata.getIdAttribute().getJavaType(); + if (jtMetadata == null) + { + columnJavaType = entityMetadata.getIdAttribute().getJavaType(); + jtMetadata = owningEntityMetadata.getRelation(relation.getMappedBy()).getJoinTableMetadata(); + pClient = delegator.getClient(owningEntityMetadata); + schema = owningEntityMetadata.getSchema(); + } + + String joinTableName = jtMetadata.getJoinTableName(); + + Set joinColumns = jtMetadata.getJoinColumns(); + Set inverseJoinColumns = jtMetadata.getInverseJoinColumns(); + + String joinColumnName = (String) joinColumns.toArray()[0]; + String inverseJoinColumnName = (String) inverseJoinColumns.toArray()[0]; + + // EntityMetadata relMetadata = + // delegator.getMetadata(relation.getTargetEntity()); + + Object entityId = PropertyAccessorHelper.getId(entity, entityMetadata); + List foreignKeys = pClient.getColumnsById(schema, joinTableName, joinColumnName, inverseJoinColumnName, + entityId, columnJavaType); + + List childrenEntities = new ArrayList(); + + if (foreignKeys != null) + { + for (Object foreignKey : foreignKeys) + { + EntityMetadata childMetadata = KunderaMetadataManager.getEntityMetadata(relation.getTargetEntity()); + + Object child = delegator.find(relation.getTargetEntity(), foreignKey); + Object obj = child instanceof EnhanceEntity && child != null ? ((EnhanceEntity) child).getEntity() + : child; + + // If child has any bidirectional relationship, process them + // here + Field biDirectionalField = relation.getBiDirectionalField()/* + * getBiDirectionalField + * ( + * entity + * . + * getClass + * ( + * ), + * relation + * . + * getTargetEntity + * ( + * )) + */; + boolean isBidirectionalRelation = (biDirectionalField != null); + + if (isBidirectionalRelation && obj != null) + { + Object columnValue = PropertyAccessorHelper.getId(obj, childMetadata); + Object[] pKeys = pClient.findIdsByColumn(entityMetadata.getSchema(), joinTableName, joinColumnName, + inverseJoinColumnName, columnValue, entityMetadata.getEntityClazz()); + List parents = delegator.find(entity.getClass(), pKeys); + PropertyAccessorHelper.set(obj, biDirectionalField, + ObjectUtils.getFieldInstance(parents, biDirectionalField)); + } + + childrenEntities.add(obj); + } + } + Field childField = relation.getProperty(); + + try + { + PropertyAccessorHelper.set( + entity, + childField, + PropertyAccessorHelper.isCollection(childField.getType()) ? ObjectUtils.getFieldInstance( + childrenEntities, childField) : childrenEntities.get(0)); + PersistenceCacheManager.addEntityToPersistenceCache(entity, delegator, entityId); + } + catch (PropertyAccessException ex) + { + throw new EntityReaderException(ex); + } + } + + /** + * Populates a a relationship collection which is of type {@link Map} from + * relationsMap into entity + * + * @param entity + * @param delegator + * @param relation + * @param relObject + * @param relationsMap + */ + private void populateCollectionFromMap(Object entity, PersistenceDelegator delegator, Relation relation, + Object relObject, Map relationsMap) + { + EntityMetadata childMetadata = KunderaMetadataManager.getEntityMetadata(relation.getTargetEntity()); + Map relationshipEntityMap = new HashMap(); // Map + // collection + // to + // be + // set + // into + // entity + + if ((relObject == null || ProxyHelper.isProxyCollection(relObject) ) && relationsMap != null && !relationsMap.isEmpty()) + { + for (String relationName : relationsMap.keySet()) + { + Object relationValue = relationsMap.get(relationName); + if (relationValue instanceof Map) + { + Map relationValueMap = (Map) relationValue; + + Client targetEntityClient = delegator.getClient(childMetadata); // Client + // for + // target + // entity + for (Object targetEntityKey : relationValueMap.keySet()) + { + // Find target entity from database + Object targetEntity = targetEntityClient.find(childMetadata.getEntityClazz(), targetEntityKey); + if (targetEntity != null && targetEntity instanceof EnhanceEntity) + { + targetEntity = ((EnhanceEntity) targetEntity).getEntity(); + } + + // Set source and target entities into Map key entity + Object mapKeyEntity = relationValueMap.get(targetEntityKey); + Class relationshipClass = relation.getMapKeyJoinClass(); + for (Field f : relationshipClass.getDeclaredFields()) + { + if (f.getType().equals(entity.getClass())) + { + PropertyAccessorHelper.set(mapKeyEntity, f, entity); + } + else if (f.getType().equals(childMetadata.getEntityClazz())) + { + PropertyAccessorHelper.set(mapKeyEntity, f, targetEntity); + } + } + + // Finally, put map key and value into collection + relationshipEntityMap.put(mapKeyEntity, targetEntity); + } + } + } + relObject = relationshipEntityMap; + } + + // Set relationship collection into original entity + PropertyAccessorHelper.set(entity, relation.getProperty(), relObject); + + // Add target entities into persistence cache + if (relObject != null && ! ProxyHelper.isProxyCollection(relObject)) + { + for (Object child : ((Map) relObject).values()) + { + if (child != null) + { + Object childId = PropertyAccessorHelper.getId(child, childMetadata); + PersistenceCacheManager.addEntityToPersistenceCache(child, delegator, childId); + } + } + } + } + + /** + * @param entity + * @param relationsMap + * @param m + * @param pd + * @param entityId + * @param relation + */ + public void setProxyRelationObject(Object entity, Map relationsMap, EntityMetadata m, + PersistenceDelegator pd, Object entityId, Relation relation) + { + String relationName = MetadataUtils.getMappedName(m, relation); + Object relationValue = relationsMap != null ? relationsMap.get(relationName) : null; + + if ((relation.getType().equals(ForeignKey.ONE_TO_ONE) || relation.getType().equals(ForeignKey.MANY_TO_ONE))) + { // One-To-One or + // Many-To-One + // relationship + + Field biDirectionalField = relation.getBiDirectionalField()/*getBiDirectionalField(entity.getClass(), relation.getTargetEntity())*/; + boolean isBidirectionalRelation = (biDirectionalField != null); + if (isBidirectionalRelation && (relationValue == null && !relation.isJoinedByPrimaryKey())) + { + EntityMetadata parentEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation + .getTargetEntity()); + Object owner = null; + + String entityName = m.getEntityClazz().getName() + "_" + entityId + "#" + + relation.getProperty().getName(); + + KunderaProxy kp = KunderaMetadata.INSTANCE.getCoreMetadata().getLazyInitializerFactory().getProxy(entityName); + + if (kp != null) + { + owner = kp.getKunderaLazyInitializer().getOwner(); + if (owner != null && owner.getClass().equals(parentEntityMetadata.getEntityClazz())) + { + + relationValue = PropertyAccessorHelper.getId(owner, parentEntityMetadata); + } + + if (relationValue != null) + { + if (log.isDebugEnabled()) + { + log.debug("Creating proxy for >> " + parentEntityMetadata.getEntityClazz().getName() + "#" + + relation.getProperty().getName() + "_" + relationValue); + } + + + Object proxy = getLazyEntity(entityName, relation.getTargetEntity(), + parentEntityMetadata.getReadIdentifierMethod(), + parentEntityMetadata.getWriteIdentifierMethod(), relationValue, pd); + PropertyAccessorHelper.set(entity, relation.getProperty(), proxy); + } + } + + } + + else if (relationValue != null) + { + if (log.isDebugEnabled()) + { + log.debug("Creating proxy for >> " + m.getEntityClazz().getName() + "#" + + relation.getProperty().getName() + "_" + relationValue); + } + + String entityName = m.getEntityClazz().getName() + "_" + entityId + "#" + + relation.getProperty().getName(); + + Object proxy = getLazyEntity(entityName, relation.getTargetEntity(), m.getReadIdentifierMethod(), + m.getWriteIdentifierMethod(), relationValue, pd); + PropertyAccessorHelper.set(entity, relation.getProperty(), proxy); + + } + else if(relation.isJoinedByPrimaryKey()) + { + if (log.isDebugEnabled()) + { + log.debug("Creating proxy for >> " + m.getEntityClazz().getName() + "#" + + relation.getProperty().getName() + "_" + relationValue); + } + + String entityName = m.getEntityClazz().getName() + "_" + entityId + "#" + + relation.getProperty().getName(); + + Object proxy = getLazyEntity(entityName, relation.getTargetEntity(), m.getReadIdentifierMethod(), + m.getWriteIdentifierMethod(), entityId, pd); + PropertyAccessorHelper.set(entity, relation.getProperty(), proxy); + } + + } + else if (relation.getType().equals(ForeignKey.ONE_TO_MANY) + || relation.getType().equals(ForeignKey.MANY_TO_MANY)) + { + ProxyCollection proxyCollection = null; + + if (relation.getPropertyType().isAssignableFrom(Set.class)) + { + proxyCollection = new ProxySet(pd, relation); + + } + else if (relation.getPropertyType().isAssignableFrom(List.class)) + { + proxyCollection = new ProxyList(pd, relation); + } + + else if (relation.getPropertyType().isAssignableFrom(Map.class)) + { + proxyCollection = new ProxyMap(pd, relation); + } + + proxyCollection.setOwner(entity); + proxyCollection.setRelationsMap(relationsMap); + + PropertyAccessorHelper.set(entity, relation.getProperty(), proxyCollection); + } + } + + private KunderaProxy getLazyEntity(String entityName, Class persistentClass, Method getIdentifierMethod, + Method setIdentifierMethod, Object id, PersistenceDelegator pd) + { + return KunderaMetadata.INSTANCE.getCoreMetadata().getLazyInitializerFactory() + .getProxy(entityName, persistentClass, getIdentifierMethod, setIdentifierMethod, id, pd); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/Coordinator.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/Coordinator.java new file mode 100644 index 000000000..d8fdb3917 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/Coordinator.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence; + +import java.util.HashMap; +import java.util.Map; + +import com.impetus.kundera.persistence.KunderaEntityTransaction.TxAction; +import com.impetus.kundera.persistence.TransactionResource.Response; + +/** + * @author vivek + * + */ +class Coordinator +{ + + // private List txResources = new + // ArrayList(); + + private Map txResources = new HashMap(); + + public Coordinator() + { + + } + + void addResource(TransactionResource resource, final String pu) + { + txResources.put(pu, resource); + } + + TransactionResource getResource(final String pu) + { + return txResources.get(pu); + } + + Response coordinate(TxAction action) + { + Response response = Response.YES; + switch (action) + { + case BEGIN: + for (TransactionResource res : txResources.values()) + { + res.onBegin(); + } + break; + + case PREPARE: + + // TODO:: need to handle case of two phase commit, in case of + // polyglot persistence. + + for (TransactionResource res : txResources.values()) + { + res.prepare(); + } + break; + + case COMMIT: + + for (TransactionResource res : txResources.values()) + { + res.onCommit(); + } + break; + + case ROLLBACK: + for (TransactionResource res : txResources.values()) + { + res.onRollback(); + } + + break; + + default: + throw new IllegalArgumentException("Invalid transaction action : " + action); + } + + return response; + } + + boolean isTransactionActive() + { + for (TransactionResource res : txResources.values()) + { + if (res.isActive()) + { + return true; + } + + } + return false; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/DefaultTransactionResource.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/DefaultTransactionResource.java new file mode 100644 index 000000000..eb068b090 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/DefaultTransactionResource.java @@ -0,0 +1,155 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.persistence.api.Batcher; + +/** + * Default transaction implementation for databases who does not support + * transactions. This can only ensure ATOMICITY out of ACID properties. + * + * @author vivek.mishra + */ +public class DefaultTransactionResource implements TransactionResource +{ + + private boolean isActive; + + private Client client; + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(DefaultTransactionResource.class); + + private List nodes = new ArrayList(); + + public DefaultTransactionResource(Client client) + { + this.client = client; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#onBegin() + */ + @Override + public void onBegin() + { + isActive = true; + + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#onCommit() + */ + @Override + public void onCommit() + { + onFlush(); + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + isActive = false; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#onFlush() + */ + public void onFlush() + { + for (Node node : nodes) + { + node.flush(); + } + + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#onRollback() + */ + @Override + public void onRollback() + { + onBatchRollBack(); + + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + isActive = false; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#prepare() + */ + @Override + public Response prepare() + { + return Response.YES; + } + + /** + * + * @param node + * @param events + */ + void syncNode(Node node) + { + nodes.add(node); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.TransactionResource#isActive() + */ + @Override + public boolean isActive() + { + return isActive; + } + + /** + * In case of rollback, clear added batch, if any. + */ + private void onBatchRollBack() + { + if (client instanceof Batcher) + { + ((Batcher) client).clear(); + } + + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerFactoryImpl.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerFactoryImpl.java new file mode 100644 index 000000000..5a21e65b1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerFactoryImpl.java @@ -0,0 +1,416 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.persistence.Cache; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.PersistenceContextType; +import javax.persistence.PersistenceUnitUtil; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.spi.PersistenceUnitTransactionType; + +import org.apache.commons.lang.NotImplementedException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaPersistenceUnitUtil; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.PersistenceUtilHelper; +import com.impetus.kundera.cache.CacheException; +import com.impetus.kundera.cache.CacheProvider; +import com.impetus.kundera.cache.NonOperationalCacheProvider; +import com.impetus.kundera.client.ClientResolverException; +import com.impetus.kundera.configure.ClientMetadataBuilder; +import com.impetus.kundera.loader.ClientFactory; +import com.impetus.kundera.loader.ClientLifeCycleManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Implementation class for {@link EntityManagerFactory} + * + * @author animesh.kumar + */ +public class EntityManagerFactoryImpl implements EntityManagerFactory +{ + + /** the log used by this class. */ + private static Logger logger = LoggerFactory.getLogger(EntityManagerFactoryImpl.class); + + /** Whether or not the factory has been closed. */ + private boolean closed; + + /** + * Persistence Unit Properties Overriden by user provided factory + * properties. + */ + private Map properties; + + // TODO: Move it to Application Metadata + /** The cache provider. */ + private CacheProvider cacheProvider; + + /** + * Array of persistence units. (Contains only one string usually except when + * persisting in multiple data-stores) + */ + private String[] persistenceUnits; + + // Transaction type + private PersistenceUnitTransactionType transactionType; + + private final KunderaPersistenceUnitUtil util; + + private final PersistenceUtilHelper.MetadataCache cache = new PersistenceUtilHelper.MetadataCache(); + + /** ClientFactory map holds one clientfactory for one persistence unit */ + private Map clientFactories = new ConcurrentHashMap(); + + /** + * Use this if you want to construct this directly. + * + * @param persistenceUnit + * used to prefix the Cassandra domains + * @param properties + * the properties + */ + public EntityManagerFactoryImpl(String persistenceUnit, Map properties) + { + Map propsMap = new HashMap(); + + if (properties != null) + { + propsMap.putAll(properties); + } + + // TODO Devise some better (JPA) way + propsMap.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + this.properties = propsMap; + this.persistenceUnits = persistenceUnit.split(Constants.PERSISTENCE_UNIT_SEPARATOR); + + // configure client factories + configureClientFactories(); + + // Initialize L2 cache + this.cacheProvider = initSecondLevelCache(); + this.cacheProvider.createCache(Constants.KUNDERA_SECONDARY_CACHE_NAME); + + // Invoke Client Loaders + // logger.info("Loading Client(s) For Persistence Unit(s) " + + // persistenceUnit); + + Set txTypes = new HashSet(); + + for (String pu : persistenceUnits) + { + PersistenceUnitTransactionType txType = KunderaMetadataManager.getPersistenceUnitMetadata(pu) + .getTransactionType(); + txTypes.add(txType); + } + + if (txTypes.size() != 1) + { + throw new IllegalArgumentException( + "For polyglot persistence, it is mandatory for all persistence units to have same Transction type."); + } + else + { + this.transactionType = txTypes.iterator().next(); + } + + this.util = new KunderaPersistenceUnitUtil(cache); + + if (logger.isDebugEnabled()) + logger.info("EntityManagerFactory created for persistence unit : " + persistenceUnit); + } + + /** + * Close the factory, releasing any resources that it holds. After a factory + * instance has been closed, all methods invoked on it will throw the + * IllegalStateException, except for isOpen, which will return false. Once + * an EntityManagerFactory has been closed, all its entity managers are + * considered to be in the closed state. + * + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#close() + */ + @Override + public final void close() + { + if (isOpen()) + { + closed = true; + + // Shut cache provider down + if (cacheProvider != null) + { + cacheProvider.shutdown(); + } + + for (String pu : persistenceUnits) + { + ((ClientLifeCycleManager) clientFactories.get(pu)).destroy(); +// KunderaMetadata.INSTANCE.unloadKunderaMetadata(pu); + } + this.persistenceUnits = null; + this.properties = null; + clientFactories.clear(); + clientFactories = new ConcurrentHashMap(); + } + else + { + throw new IllegalStateException("entity manager factory has been closed"); + } + } + + /** + * Create a new application-managed EntityManager. This method returns a new + * EntityManager instance each time it is invoked. The isOpen method will + * return true on the returned instance. + * + * @return entity manager instance + * @throws IllegalStateException + * if the entity manager factory has been closed + */ + @Override + public final EntityManager createEntityManager() + { + // For Application managed persistence context, type is always EXTENDED + if (isOpen()) + { + return new EntityManagerImpl(this, transactionType, PersistenceContextType.EXTENDED); + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Create a new application-managed EntityManager with the specified Map of + * properties. This method returns a new EntityManager instance each time it + * is invoked. The isOpen method will return true on the returned instance. + * + * @param map + * properties for entity manager + * @return entity manager instance + * @throws IllegalStateException + * if the entity manager factory has been closed + */ + @Override + public final EntityManager createEntityManager(Map map) + { + // For Application managed persistence context, type is always EXTENDED + if (isOpen()) + { + return new EntityManagerImpl(this, map, transactionType, PersistenceContextType.EXTENDED); + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Indicates whether the factory is open. Returns true until the factory has + * been closed. + * + * @return boolean indicating whether the factory is open + * @see javax.persistence.EntityManagerFactory#isOpen() + */ + @Override + public final boolean isOpen() + { + return !closed; + } + + /** + * Return an instance of CriteriaBuilder for the creation of CriteriaQuery + * objects. + * + * @return CriteriaBuilder instance + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#getCriteriaBuilder() + */ + @Override + public CriteriaBuilder getCriteriaBuilder() + { + if (isOpen()) + { + throw new NotImplementedException("Criteria Query currently not supported by Kundera"); + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Return an instance of Metamodel interface for access to the metamodel of + * the persistence unit. + * + * @return Metamodel instance + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#getMetamodel() + */ + @Override + public Metamodel getMetamodel() + { + if (isOpen()) + { + return KunderaMetadataManager.getMetamodel(getPersistenceUnits()); + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Get the properties and associated values that are in effect for the + * entity manager factory. Changing the contents of the map does not change + * the configuration in effect. + * + * @return properties + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#getProperties() + */ + @Override + public Map getProperties() + { + if (isOpen()) + { + return properties; + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Access the cache that is associated with the entity manager factory (the + * "second level cache"). + * + * @return instance of the Cache interface + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#getCache() + */ + @Override + public Cache getCache() + { + if (isOpen()) + { + return cacheProvider.getCache(Constants.KUNDERA_SECONDARY_CACHE_NAME); + } + throw new IllegalStateException("entity manager factory has been closed"); + } + + /** + * Return interface providing access to utility methods for the persistence + * unit. + * + * @return PersistenceUnitUtil interface + * @throws IllegalStateException + * if the entity manager factory has been closed + * @see javax.persistence.EntityManagerFactory#getPersistenceUnitUtil() + */ + @Override + public PersistenceUnitUtil getPersistenceUnitUtil() + { + if (!isOpen()) + { + throw new IllegalStateException("EntityManagerFactory is closed"); + } + return this.util; + } + + /** + * Initialize and load clientFactory for all persistenceUnit with external + * properties. + * + * @param persistenceUnit + * @param externalProperties + */ + private void configureClientFactories() + { + ClientMetadataBuilder builder = new ClientMetadataBuilder(getProperties(), getPersistenceUnits()); + builder.buildClientFactoryMetadata(clientFactories); + } + + /** + * Inits the second level cache. + * + * @return the cache provider + */ + private CacheProvider initSecondLevelCache() + { + String classResourceName = (String) getProperties().get(PersistenceProperties.KUNDERA_CACHE_CONFIG_RESOURCE); + String cacheProviderClassName = (String) getProperties() + .get(PersistenceProperties.KUNDERA_CACHE_PROVIDER_CLASS); + + CacheProvider cacheProvider = null; + if (cacheProviderClassName != null) + { + try + { + Class cacheProviderClass = (Class) Class.forName(cacheProviderClassName); + cacheProvider = cacheProviderClass.newInstance(); + cacheProvider.init(classResourceName); + } + catch (ClassNotFoundException e) + { + throw new CacheException("Could not find class " + cacheProviderClassName + + ". Check whether you spelled it correctly in persistence.xml", e); + } + catch (InstantiationException e) + { + throw new CacheException("Could not instantiate " + cacheProviderClassName, e); + } + catch (IllegalAccessException e) + { + throw new CacheException(e); + } + } + if (cacheProvider == null) + { + cacheProvider = new NonOperationalCacheProvider(); + } + return cacheProvider; + } + + /** + * Gets the persistence units. + * + * @return the persistence units + */ + String[] getPersistenceUnits() + { + return persistenceUnits; + } + + ClientFactory getClientFactory(final String pu) + { + ClientFactory clientFactory = clientFactories.get(pu); + if (clientFactory != null) + { + return clientFactory; + } + logger.error("Client Factory Not Configured For Specified Client Type : "); + throw new ClientResolverException("Client Factory Not Configured For Specified Client Type."); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerImpl.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerImpl.java new file mode 100644 index 000000000..4abb96a22 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerImpl.java @@ -0,0 +1,995 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.util.HashMap; +import java.util.Map; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.persistence.EntityExistsException; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.EntityNotFoundException; +import javax.persistence.EntityTransaction; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.PersistenceContextType; +import javax.persistence.Query; +import javax.persistence.TransactionRequiredException; +import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.spi.PersistenceUnitTransactionType; +import javax.transaction.UserTransaction; + +import org.apache.commons.lang.NotImplementedException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientResolverException; +import com.impetus.kundera.loader.ClientFactory; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.persistence.context.PersistenceCache; +import com.impetus.kundera.persistence.jta.KunderaJTAUserTransaction; +import com.impetus.kundera.query.KunderaTypedQuery; +import com.impetus.kundera.query.QueryImpl; + +/** + * The Class EntityManagerImpl. + * + * @author animesh.kumar + */ +public class EntityManagerImpl implements EntityManager, ResourceManager +{ + + /** The Constant log. */ + private static Logger logger = LoggerFactory.getLogger(EntityManagerImpl.class); + + /** The factory. */ + private EntityManagerFactory factory; + + /** The closed. */ + private boolean closed; + + /** Flush mode for this EM, default is AUTO. */ + private FlushModeType flushMode = FlushModeType.AUTO; + + /** Properties provided by user at the time of EntityManager Creation. */ + private Map properties; + + /** Properties provided by user at the time of EntityManager Creation. */ + private PersistenceDelegator persistenceDelegator; + + /** Persistence Context Type (Transaction/ Extended) */ + private PersistenceContextType persistenceContextType; + + /** Transaction Type (JTA/ RESOURCE_LOCAL) */ + private PersistenceUnitTransactionType transactionType; + + private PersistenceCache persistenceCache; + + private UserTransaction utx; + + private EntityTransaction entityTransaction; + + /** + * Instantiates a new entity manager impl. + * + * @param factory + * the factory + * @param properties + * the properties + */ + EntityManagerImpl(EntityManagerFactory factory, Map properties, PersistenceUnitTransactionType transactionType, + PersistenceContextType persistenceContextType) + { + this(factory, transactionType, persistenceContextType); + this.properties = properties; + + getPersistenceDelegator().populateClientProperties(this.properties); + } + + /** + * Instantiates a new entity manager impl. + * + * @param factory + * the factory + */ + EntityManagerImpl(EntityManagerFactory factory, PersistenceUnitTransactionType transactionType, + PersistenceContextType persistenceContextType) + { + this.factory = factory; + this.persistenceContextType = persistenceContextType; + this.transactionType = transactionType; + if (logger.isDebugEnabled()) + { + logger.debug("Creating EntityManager for persistence unit : " + getPersistenceUnit()); + } + // session = new EntityManagerSession((Cache) factory.getCache()); + this.persistenceCache = new PersistenceCache(); + this.persistenceCache.setPersistenceContextType(persistenceContextType); + + this.persistenceDelegator = new PersistenceDelegator(this.persistenceCache); + + for (String pu : ((EntityManagerFactoryImpl) this.factory).getPersistenceUnits()) + { + this.persistenceDelegator.loadClient(pu, discoverClient(pu)); + } + + if (logger.isDebugEnabled()) + { + logger.debug("Created EntityManager for persistence unit : " + getPersistenceUnit()); + } + } + + /** + * Make an instance managed and persistent. + * + * @param entity + * @throws EntityExistsException + * if the entity already exists. (If the entity already exists, + * the EntityExistsException may be thrown when the persist + * operation is invoked, or the EntityExistsException or another + * PersistenceException may be thrown at flush or commit time.) + * @throws IllegalArgumentException + * if the instance is not an entity + * @throws TransactionRequiredException + * if invoked on a container-managed entity manager of type + * PersistenceContextType.TRANSACTION and there is no + * transaction + */ + @Override + public final void persist(Object e) + { + checkClosed(); + checkTransactionNeeded(); + try + { + getPersistenceDelegator().persist(e); + } + catch (Exception ex) + { + // onRollBack. + doRollback(); + throw new KunderaException(ex); + } + } + + /** + * Merge the state of the given entity into the current persistence context. + * + * @param entity + * @return the managed instance that the state was merged to + * @throws IllegalArgumentException + * if instance is not an entity or is a removed entity + * @throws TransactionRequiredException + * if invoked on a container-managed entity manager of type + * PersistenceContextType.TRANSACTION and there is no + * transaction + * @see javax.persistence.EntityManager#merge(java.lang.Object) + */ + @Override + public final E merge(E e) + { + checkClosed(); + checkTransactionNeeded(); + try + { + return getPersistenceDelegator().merge(e); + } + catch (Exception ex) + { + // on Rollback + doRollback(); + throw new KunderaException(ex); + } + } + + /** + * Remove the entity instance. + * + * @param entity + * @throws IllegalArgumentException + * if the instance is not an entity or is a detached entity + * @throws TransactionRequiredException + * if invoked on a container-managed entity manager of type + * PersistenceContextType.TRANSACTION and there is no + * transaction + */ + @Override + public final void remove(Object e) + { + checkClosed(); + checkTransactionNeeded(); + try + { + getPersistenceDelegator().remove(e); + } + catch (Exception ex) + { + // on rollback. + doRollback(); + throw new KunderaException(ex); + } + } + + /** + * Find by primary key. Search for an entity of the specified class and + * primary key. If the entity instance is contained in the persistence + * context it is returned from there. + * + * @param entityClass + * @param primaryKey + * @return the found entity instance or null if the entity does not exist + * @throws IllegalArgumentException + * if the first argument does not denote an entity type or the + * second argument is is not a valid type for that entity’s + * primary key or is null + * @see javax.persistence.EntityManager#find(java.lang.Class, + * java.lang.Object) + */ + + @Override + public final E find(Class entityClass, Object primaryKey) + { + checkClosed(); + checkTransactionNeeded(); + return getPersistenceDelegator().findById(entityClass, primaryKey); + } + + /** + * Find by primary key, using the specified properties. Search for an entity + * of the specified class and primary key. If the entity instance is + * contained in the persistence context it is returned from there. If a + * vendor-specific property or hint is not recognized, it is silently + * ignored. + * + * @param entityClass + * @param primaryKey + * @param properties + * standard and vendor-specific properties and hints + * @return the found entity instance or null if the entity does not exist + * @throws IllegalArgumentException + * if the first argument does not denote an entity type or the + * second argument is is not a valid type for that entity’s + * primary key or is null + * @see javax.persistence.EntityManager#find(java.lang.Class, + * java.lang.Object, java.util.Map) + */ + @Override + public T find(Class entityClass, Object primaryKey, Map properties) + { + checkClosed(); + checkTransactionNeeded(); + + // Store current properties in a variable for post-find reset + Map currentProperties = getProperties(); + + // Populate properties in client + getPersistenceDelegator().populateClientProperties(properties); + T result = find(entityClass, primaryKey); + + // Reset Client properties + getPersistenceDelegator().populateClientProperties(currentProperties); + return result; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#find(java.lang.Class, + * java.lang.Object, javax.persistence.LockModeType) + */ + @Override + public T find(Class paramClass, Object paramObject, LockModeType paramLockModeType) + { + checkClosed(); + throw new NotImplementedException("Lock mode type currently not supported by Kundera"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#find(java.lang.Class, + * java.lang.Object, javax.persistence.LockModeType, java.util.Map) + */ + @Override + public T find(Class arg0, Object arg1, LockModeType arg2, Map arg3) + { + checkClosed(); + throw new NotImplementedException("Lock mode type currently not supported by Kundera"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#clear() + */ + @Override + public final void clear() + { + checkClosed(); + // session.clear(); + + // TODO Do we need a client and persistenceDelegator close here? + if (!PersistenceUnitTransactionType.JTA.equals(this.transactionType)) + { + getPersistenceDelegator().clear(); + } + } + + @Override + public final void close() + { + checkClosed(); + // session.clear(); + // session = null; + if (!PersistenceUnitTransactionType.JTA.equals(this.transactionType)) + { + getPersistenceDelegator().clear(); + } + getPersistenceDelegator().close(); + + this.closed = true; + } + + /** + * Check if the instance is a managed entity instance belonging to the + * current persistence context. + * + * @param entity + * @return boolean indicating if entity is in persistence context + * @throws IllegalArgumentException + * if not an entity + * @see javax.persistence.EntityManager#contains(java.lang.Object) + */ + @Override + public final boolean contains(Object entity) + { + checkClosed(); + + return getPersistenceDelegator().contains(entity); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createQuery(java.lang.String) + */ + @Override + public final Query createQuery(String query) + { + checkClosed(); + checkTransactionNeeded(); + return getPersistenceDelegator().createQuery(query); + } + + @Override + public final void flush() + { + checkClosed(); + getPersistenceDelegator().doFlush(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getDelegate() + */ + @Override + public final Object getDelegate() + { + checkClosed(); + return getPersistenceDelegator().getDelegate(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createNamedQuery(java.lang.String) + */ + @Override + public final Query createNamedQuery(String name) + { + checkClosed(); + checkTransactionNeeded(); + return getPersistenceDelegator().createQuery(name); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String) + */ + @Override + public final Query createNativeQuery(String sqlString) + { + checkClosed(); + throw new NotImplementedException("Please use createNativeQuery(String sqlString, Class resultClass) instead."); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String, + * java.lang.Class) + */ + @Override + public final Query createNativeQuery(String sqlString, Class resultClass) + { + checkClosed(); + checkTransactionNeeded(); + // Add to meta data first. + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + + if (appMetadata.getQuery(sqlString) == null) + { + appMetadata.addQueryToCollection(sqlString, sqlString, true, resultClass); + } + + return getPersistenceDelegator().createQuery(sqlString); + + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createNativeQuery(java.lang.String, + * java.lang.String) + */ + @Override + public final Query createNativeQuery(String sqlString, String resultSetMapping) + { + checkClosed(); + throw new NotImplementedException("ResultSetMapping currently not supported by Kundera. " + + "Please use createNativeQuery(String sqlString, Class resultClass) instead."); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getReference(java.lang.Class, + * java.lang.Object) + */ + @Override + public final T getReference(Class entityClass, Object primaryKey) + { + checkClosed(); + throw new NotImplementedException("getReference currently not supported by Kundera"); + } + + @Override + public final FlushModeType getFlushMode() + { + checkClosed(); + return this.flushMode; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getTransaction() + */ + @Override + public final EntityTransaction getTransaction() + { + checkClosed(); + if (this.transactionType == PersistenceUnitTransactionType.JTA) + { + throw new IllegalStateException("A JTA EntityManager cannot use getTransaction()"); + } + + if (this.entityTransaction == null) + { + this.entityTransaction = new KunderaEntityTransaction(this); + } + return this.entityTransaction; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#joinTransaction() + */ + @Override + public final void joinTransaction() + { + checkClosed(); + if (this.utx != null) + { + return; + } + else + { + throw new TransactionRequiredException("No transaction in progress"); + } + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#lock(java.lang.Object, + * javax.persistence.LockModeType) + */ + @Override + public final void lock(Object entity, LockModeType lockMode) + { + checkClosed(); + throw new NotImplementedException("lock currently not supported by Kundera"); + } + + /** + * Refresh the state of the instance from the database, overwriting changes + * made to the entity, if any. + * + * @param entity + * @throws IllegalArgumentException + * if the instance is not an entity or the entity is not managed + * @throws TransactionRequiredException + * if invoked on a container-managed entity manager of type + * PersistenceContextType.TRANSACTION and there is no + * transaction + * @throws EntityNotFoundException + * if the entity no longer exists in the database + * @see javax.persistence.EntityManager#refresh(java.lang.Object) + */ + @Override + public final void refresh(Object entity) + { + checkClosed(); + + checkTransactionNeeded(); + + getPersistenceDelegator().refresh(entity); + } + + /** + * Refresh the state of the instance from the database, using the specified + * properties, and overwriting changes made to the entity, if any. If a + * vendor-specific property or hint is not recognized, it is silently + * ignored. + * + * @param entity + * @param properties + * standard and vendor-specific properties and hints + * @throws IllegalArgumentException + * if the instance is not an entity or the entity is not managed + * @throws TransactionRequiredException + * if invoked on a container-managed entity manager of type + * PersistenceContextType.TRANSACTION and there is no + * transaction + * @throws EntityNotFoundException + * if the entity no longer exists in the database + * @see javax.persistence.EntityManager#refresh(java.lang.Object, + * java.util.Map) + */ + @Override + public void refresh(Object entity, Map properties) + { + // Store current properties in a variable for post-find reset + Map currentProperties = getProperties(); + + // Populate properties in client + getPersistenceDelegator().populateClientProperties(properties); + + // Refresh state of entity + refresh(entity); + + // Reset Client properties + getPersistenceDelegator().populateClientProperties(currentProperties); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#lock(java.lang.Object, + * javax.persistence.LockModeType, java.util.Map) + */ + @Override + public void lock(Object paramObject, LockModeType paramLockModeType, Map paramMap) + { + checkClosed(); + throw new NotImplementedException("lock currently not supported by Kundera"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#refresh(java.lang.Object, + * javax.persistence.LockModeType) + */ + @Override + public void refresh(Object paramObject, LockModeType paramLockModeType) + { + checkClosed(); + throw new NotImplementedException("Lock mode type currently not supported by Kundera"); + + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#refresh(java.lang.Object, + * javax.persistence.LockModeType, java.util.Map) + */ + @Override + public void refresh(Object paramObject, LockModeType paramLockModeType, Map paramMap) + { + checkClosed(); + throw new NotImplementedException("LockModeType currently not supported by Kundera"); + } + + /** + * Remove the given entity from the persistence context, causing a managed + * entity to become detached. Unflushed changes made to the entity if any + * (including removal of the entity), will not be synchronized to the + * database. Entities which previously referenced the detached entity will + * continue to reference it. + * + * @param entity + * @throws IllegalArgumentException + * if the instance is not an entity + * @see javax.persistence.EntityManager#detach(java.lang.Object) + */ + @Override + public void detach(Object entity) + { + checkClosed(); + + if (entity == null) + { + throw new IllegalArgumentException("Entity is null, can't detach it"); + } + getPersistenceDelegator().detach(entity); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getLockMode(java.lang.Object) + */ + @Override + public LockModeType getLockMode(Object paramObject) + { + checkClosed(); + throw new NotImplementedException("Lock mode type currently not supported by Kundera"); + } + + /** + * Set an entity manager property or hint. If a vendor-specific property or + * hint is not recognized, it is silently ignored. + * + * @param propertyName + * name of property or hint + * @param value + * @throws IllegalArgumentException + * if the second argument is not valid for the implementation + * @see javax.persistence.EntityManager#setProperty(java.lang.String, + * java.lang.Object) + */ + @Override + public void setProperty(String paramString, Object paramObject) + { + checkClosed(); + if (getProperties() == null) + { + this.properties = new HashMap(); + } + + this.properties.put(paramString, paramObject); + getPersistenceDelegator().populateClientProperties(this.properties); + } + + /* + * (non-Javadoc) + * + * @see + * javax.persistence.EntityManager#createQuery(javax.persistence.criteria + * .CriteriaQuery) + */ + @Override + public TypedQuery createQuery(CriteriaQuery paramCriteriaQuery) + { + checkClosed(); + throw new NotImplementedException("Criteria Query currently not supported by Kundera"); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createQuery(java.lang.String, + * java.lang.Class) + */ + @Override + public TypedQuery createQuery(String paramString, Class paramClass) + { + Query q = createQuery(paramString); + return onTypedQuery(paramClass, q); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#createNamedQuery(java.lang.String, + * java.lang.Class) + */ + @Override + public TypedQuery createNamedQuery(String paramString, Class paramClass) + { + Query q = createNamedQuery(paramString); + return onTypedQuery(paramClass, q); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#unwrap(java.lang.Class) + */ + @Override + public T unwrap(Class paramClass) + { + checkClosed(); + throw new NotImplementedException("unwrap currently not supported by Kundera"); + } + + @Override + public final void setFlushMode(FlushModeType flushMode) + { + checkClosed(); + this.flushMode = flushMode; + getPersistenceDelegator().setFlushMode(flushMode); + } + + /** + * Get the properties and hints and associated values that are in effect for + * the entity manager. Changing the contents of the map does not change the + * configuration in effect. + * + * @return map of properties and hints in effect + */ + @Override + public Map getProperties() + { + checkClosed(); + return this.properties; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getEntityManagerFactory() + */ + @Override + public EntityManagerFactory getEntityManagerFactory() + { + checkClosed(); + return this.factory; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getCriteriaBuilder() + */ + @Override + public CriteriaBuilder getCriteriaBuilder() + { + checkClosed(); + return getEntityManagerFactory().getCriteriaBuilder(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#getMetamodel() + */ + @Override + public Metamodel getMetamodel() + { + checkClosed(); + return getEntityManagerFactory().getMetamodel(); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityManager#isOpen() + */ + @Override + public final boolean isOpen() + { + return !closed; + } + + /** + * Check closed. + */ + private void checkClosed() + { + if (!isOpen()) + { + throw new IllegalStateException("EntityManager has already been closed."); + } + } + + private void checkTransactionNeeded() + { + onLookUp(transactionType); + + if ((getPersistenceContextType() != PersistenceContextType.TRANSACTION) + || (getPersistenceDelegator().isTransactionInProgress())) + { + return; + } + throw new TransactionRequiredException( + "no transaction is in progress for a TRANSACTION type persistence context"); + } + + private void onLookUp(PersistenceUnitTransactionType transactionType) + { + // TODO transaction should not be null; + if (transactionType != null && transactionType.equals(PersistenceUnitTransactionType.JTA)) + { + if (this.entityTransaction == null) + { + this.entityTransaction = new KunderaEntityTransaction(this); + } + Context ctx; + try + { + ctx = new InitialContext(); + + this.utx = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); + + if (this.utx == null) + { + throw new KunderaException( + "Lookup for UserTransaction returning null for :{java:comp/UserTransaction}"); + } + // TODO what is need to check? + if (!(this.utx instanceof KunderaJTAUserTransaction)) + { + throw new KunderaException("Please bind [" + KunderaJTAUserTransaction.class.getName() + + "] for :{java:comp/UserTransaction} lookup" + this.utx.getClass()); + } + + if (!this.entityTransaction.isActive()) + { + this.entityTransaction.begin(); + this.setFlushMode(FlushModeType.COMMIT); + ((KunderaJTAUserTransaction) this.utx).setImplementor(this); + } + + } + catch (NamingException e) + { + logger.error("Error during initialization of entity manager, Caused by:", e); + throw new KunderaException(e); + } + + } + } + + /** + * Returns Persistence unit (or comma separated units) associated with EMF. + * + * @return the persistence unit + */ + private String getPersistenceUnit() + { + return (String) getEntityManagerFactory().getProperties().get(Constants.PERSISTENCE_UNIT_NAME); + } + + /** + * Gets the persistence delegator. + * + * @return the persistence delegator + */ + PersistenceDelegator getPersistenceDelegator() + { + checkClosed(); + return this.persistenceDelegator; + } + + /** + * @return the persistenceContextType + */ + private PersistenceContextType getPersistenceContextType() + { + return this.persistenceContextType; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.EntityImplementor#doCommit() + */ + @Override + public void doCommit() + { + checkClosed(); + this.entityTransaction.commit(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.EntityImplementor#doRollback() + */ + @Override + public void doRollback() + { + checkClosed(); + if (this.entityTransaction != null) + { + this.entityTransaction.rollback(); + } + else + { + getPersistenceDelegator().rollback(); + } + } + + /** + * Validates if expected result class is matching with supplied one, else + * throws {@link IllegalArgumentException} + * + * @param + * object type + * @param paramClass + * expected result class + * @param q + * query + * @return typed query instance. + */ + private TypedQuery onTypedQuery(Class paramClass, Query q) + { + if (paramClass.equals(((QueryImpl) q).getKunderaQuery().getEntityClass()) || paramClass.equals(Object.class)) + { + return new KunderaTypedQuery(q); + } + + throw new IllegalArgumentException("Mismatch in expected return type. Expected:" + paramClass + + " But actual class is:" + ((QueryImpl) q).getKunderaQuery().getEntityClass()); + } + + /** + * Gets the client. + * + * @param persistenceUnit + * the persistence unit + * @return the client + */ + private Client discoverClient(String persistenceUnit) + { + logger.info("Returning client instance for:" + persistenceUnit); + + ClientFactory clientFactory = ((EntityManagerFactoryImpl) getEntityManagerFactory()) + .getClientFactory(persistenceUnit); + if (clientFactory != null) + { + return clientFactory.getClientInstance(); + } + throw new ClientResolverException(" No client configured for: " + persistenceUnit); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerSession.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerSession.java new file mode 100644 index 000000000..797f36238 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityManagerSession.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.cache.Cache; + +/** + * The Class EntityManagerSession. + */ +public class EntityManagerSession +{ + + /** The Constant log. */ + private static final Logger LOG = LoggerFactory.getLogger(EntityManagerSession.class); + + /** cache is used to store objects retrieved in this EntityManager session. */ + private Map sessionCache; + + /** The l2 cache. */ + private Cache l2Cache; // L2 Cache + + /** + * Instantiates a new entity manager cache. + * + * @param cache + * the cache + */ + public EntityManagerSession(Cache cache) + { + this.sessionCache = new ConcurrentHashMap(); + setL2Cache(cache); + } + + /** + * Find in cache. + * + * @param + * the generic type + * @param entityClass + * the entity class + * @param id + * the id + * @return the t + */ + @SuppressWarnings("unchecked") + protected T lookup(Class entityClass, Object id) + { + String key = cacheKey(entityClass, id); + LOG.debug("Reading from L1 >> " + key); + T o = (T) sessionCache.get(key); + + // go to second-level cache + if (o == null) + { + LOG.debug("Reading from L2 >> " + key); + Cache c = (Cache) getL2Cache(); + if (c != null) + { + o = (T) c.get(key); + if (o != null) + { + LOG.debug("Found item in second level cache!"); + } + } + } + return o; + } + + /** + * Store in L1 only. + * + * @param id + * the id + * @param entity + * the entity + */ + protected void store(Object id, Object entity) + { + store(id, entity, Boolean.TRUE); + } + + /** + * Save to cache. + * + * @param id + * the id + * @param entity + * the entity + * @param spillOverToL2 + * the spill over to l2 + */ + protected void store(Object id, Object entity, boolean spillOverToL2) + { + String key = cacheKey(entity.getClass(), id); + LOG.debug("Writing to L1 >> " + key); + sessionCache.put(key, entity); + + if (spillOverToL2) + { + LOG.debug("Writing to L2 >>" + key); + // save to second level cache + Cache c = (Cache) getL2Cache(); + if (c != null) + { + c.put(key, entity); + } + } + } + + /** + * Removes the. + * + * @param + * the generic type + * @param entityClass + * the entity class + * @param id + * the id + */ + protected void remove(Class entityClass, Object id) + { + remove(entityClass, id, Boolean.TRUE); + } + + /** + * Removes the from cache. + * + * @param + * the generic type + * @param entityClass + * the entity class + * @param id + * the id + * @param spillOverToL2 + * the spill over to l2 + */ + protected void remove(Class entityClass, Object id, boolean spillOverToL2) + { + String key = cacheKey(entityClass, id); + LOG.debug("Removing from L1 >> " + key); + Object o = sessionCache.remove(key); + + if (spillOverToL2) + { + LOG.debug("Removing from L2 >> " + key); + Cache c = (Cache) getL2Cache(); + if (c != null) + { + c.evict(entityClass, key); + } + } + } + + /** + * Cache key. + * + * @param clazz + * the clazz + * @param id + * the id + * + * @return the string + */ + private String cacheKey(Class clazz, Object id) + { + return clazz.getName() + "_" + id; + } + + /** + * Clear. + */ + public final void clear() + { + sessionCache = new ConcurrentHashMap(); + + // Clear L2 Cahce + if (getL2Cache() != null) + { + getL2Cache().evictAll(); + } + } + + /** + * Gets the l2 cache. + * + * @return the l2Cache + */ + public Cache getL2Cache() + { + return l2Cache; + } + + /** + * Sets the l2 cache. + * + * @param l2Cache + * the l2Cache to set + */ + public void setL2Cache(Cache l2Cache) + { + this.l2Cache = l2Cache; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReader.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReader.java new file mode 100644 index 000000000..0fdbdaed9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReader.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import java.util.List; +import java.util.Map; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The Interface EntityReader. + * + * @author vivek.mishra + * + * Interface to provide declarations for methods responsible for entity + * read operations.(Except queries). + */ +public interface EntityReader +{ + + /** + * Method responsible for reading back entity and relations using secondary + * indexes(if it holds any relation), else retrieve row keys using lucene. + * + * @param m + * entity meta data + * @param relationNames + * relation names + * @param isParent + * if entity is not holding any relation. + * @param client + * client instance + * @return list of wrapped enhance entities. + */ + List populateRelation(EntityMetadata m, Client client, int maxResults); + + /** + * Returns populated entity along with all relational value. + * + * @param e + * enhance entity + * @param graphs + * entity graph + * @param collectionHolder + * collection holder. + * @param client + * client + * @param m + * entity meta data + * @param persistenceDelegeator + * persistence delegator. + * @param lazily loaded. true if invoked over lazily fetched object. + * @return populate entity. + * @throws Exception + * the exception + */ + + Object recursivelyFindEntities(Object entity, Map relationsMap, EntityMetadata m, + PersistenceDelegator pd, boolean lazilyLoaded); + + /** + * Find by id. + * + * @param primaryKey + * the primary key + * @param m + * the m + * @param relationNames + * the relation names + * @param client + * the client + * @return the enhance entity + */ + EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReaderException.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReaderException.java new file mode 100644 index 000000000..6d93ddbec --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/EntityReaderException.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh + * + */ +public class EntityReaderException extends KunderaException +{ + + /** + * + */ + public EntityReaderException() + { + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + */ + public EntityReaderException(String arg0) + { + super(arg0); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + */ + public EntityReaderException(Throwable arg0) + { + super(arg0); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + * @param arg1 + */ + public EntityReaderException(String arg0, Throwable arg1) + { + super(arg0, arg1); + // TODO Auto-generated constructor stub + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/IdGenerator.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/IdGenerator.java new file mode 100644 index 000000000..52daaf52d --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/IdGenerator.java @@ -0,0 +1,183 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import javax.persistence.GenerationType; +import javax.persistence.metamodel.Metamodel; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.generator.AutoGenerator; +import com.impetus.kundera.generator.SequenceGenerator; +import com.impetus.kundera.generator.TableGenerator; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.IdDiscriptor; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Generate id for entity when {@GeneratedValue} annotation + * given. + * + * @author Kuldeep.Mishra + * + */ +public class IdGenerator +{ + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(IdGenerator.class); + + public void generateAndSetId(Object e, EntityMetadata m, PersistenceDelegator pd) + { + Metamodel metamodel = KunderaMetadataManager.getMetamodel(m.getPersistenceUnit()); + IdDiscriptor keyValue = ((MetamodelImpl) metamodel).getKeyValue(e.getClass().getName()); + + if (keyValue != null) + { + Client client = pd.getClient(m); + + String clientFactoryName = KunderaMetadataManager.getPersistenceUnitMetadata(m.getPersistenceUnit()) + .getClient(); + if (clientFactoryName != null + && !clientFactoryName.equalsIgnoreCase("com.impetus.client.rdbms.RDBMSClientFactory")) + { + if (client != null) + { + GenerationType type = keyValue.getStrategy(); + switch (type) + { + case TABLE: + onTableGenerator(m, client, keyValue, e); + break; + case SEQUENCE: + onSequenceGenerator(m, client, keyValue, e); + break; + case AUTO: + onAutoGenerator(m, client, e); + break; + case IDENTITY: + throw new UnsupportedOperationException(GenerationType.class.getSimpleName() + "." + type + + " Strategy not supported by this client :" + client.getClass().getName()); + } + } + } + else + { + int hashCode = e.hashCode(); + Object generatedId = PropertyAccessorHelper.fromSourceToTargetClass(m.getIdAttribute().getJavaType(), + Integer.class, new Integer(hashCode)); + PropertyAccessorHelper.setId(e, m, generatedId); + } + } + } + + /** + * Generate Id when given auto generation strategy. + * + * @param m + * @param client + * @param e + */ + private void onAutoGenerator(EntityMetadata m, Client client, Object e) + { + if (client instanceof AutoGenerator) + { + Object generatedId = ((AutoGenerator) client).generate(); + try + { + generatedId = PropertyAccessorHelper.fromSourceToTargetClass(m.getIdAttribute().getJavaType(), + generatedId.getClass(), generatedId); + PropertyAccessorHelper.setId(e, m, generatedId); + return; + } + catch (IllegalArgumentException iae) + { + log.error("Unknown data type for ids : " + m.getIdAttribute().getJavaType()); + throw new KunderaException("Unknown data type for ids : " + m.getIdAttribute().getJavaType(), iae); + } + } + throw new IllegalArgumentException(GenerationType.class.getSimpleName() + "." + GenerationType.AUTO + + " Strategy not supported by this client :" + client.getClass().getName()); + } + + /** + * Generate Id when given sequence generation strategy. + * + * @param m + * @param client + * @param keyValue + * @param e + */ + private void onSequenceGenerator(EntityMetadata m, Client client, IdDiscriptor keyValue, Object e) + { + if (client instanceof SequenceGenerator) + { + Object generatedId = ((SequenceGenerator) client).generate(keyValue.getSequenceDiscriptor()); + try + { + generatedId = PropertyAccessorHelper.fromSourceToTargetClass(m.getIdAttribute().getJavaType(), + generatedId.getClass(), generatedId); + PropertyAccessorHelper.setId(e, m, generatedId); + return; + } + catch (IllegalArgumentException iae) + { + log.error("Unknown integral data type for ids : " + m.getIdAttribute().getJavaType()); + throw new KunderaException("Unknown integral data type for ids : " + m.getIdAttribute().getJavaType(), + iae); + } + } + throw new IllegalArgumentException(GenerationType.class.getSimpleName() + "." + GenerationType.SEQUENCE + + " Strategy not supported by this client :" + client.getClass().getName()); + } + + /** + * Generate Id when given table generation strategy. + * + * @param m + * @param client + * @param keyValue + * @param e + */ + private void onTableGenerator(EntityMetadata m, Client client, IdDiscriptor keyValue, Object e) + { + if (client instanceof TableGenerator) + { + Object generatedId = ((TableGenerator) client).generate(keyValue.getTableDiscriptor()); + try + { + generatedId = PropertyAccessorHelper.fromSourceToTargetClass(m.getIdAttribute().getJavaType(), + generatedId.getClass(), generatedId); + PropertyAccessorHelper.setId(e, m, generatedId); + return; + } + catch (IllegalArgumentException iae) + { + log.error("Unknown integral data type for ids : " + m.getIdAttribute().getJavaType()); + throw new KunderaException("Unknown integral data type for ids : " + m.getIdAttribute().getJavaType(), + iae); + } + } + throw new IllegalArgumentException(GenerationType.class.getSimpleName() + "." + GenerationType.TABLE + + " Strategy not supported by this client :" + client.getClass().getName()); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaEntityTransaction.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaEntityTransaction.java new file mode 100644 index 000000000..a7c2aab90 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaEntityTransaction.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence; + +import javax.persistence.EntityManager; +import javax.persistence.EntityTransaction; + +/** + * Class implements EntityTransaction interface. It implements + * begin/commit/roll back and other methods. + * + * @author vivek.mishra + * + */ +public class KunderaEntityTransaction implements EntityTransaction +{ + private EntityManager entityManager; + + private Coordinator coordinator; + + private Boolean rollbackOnly; + + enum TxAction + { + BEGIN, COMMIT, ROLLBACK, PREPARE; + } + + KunderaEntityTransaction(EntityManager entityManager) + { + this.entityManager = entityManager; + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#begin() + */ + @Override + public void begin() + { + if (isActive()) + { + throw new IllegalStateException("Transaction is already active"); + } + else + { + this.coordinator = ((EntityManagerImpl) entityManager).getPersistenceDelegator().getCoordinator(); + ((EntityManagerImpl) entityManager).getPersistenceDelegator().begin(); // transaction + // de-marcation. + this.coordinator.coordinate(TxAction.BEGIN); + } + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#commit() + */ + @Override + public void commit() + { + if (!getRollbackOnly()) + { + onTransaction(TxAction.COMMIT); + ((EntityManagerImpl) entityManager).getPersistenceDelegator().commit(); + } + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#getRollbackOnly() + */ + @Override + public boolean getRollbackOnly() + { + if (isActive()) + { + return rollbackOnly != null ? rollbackOnly : false; + } + else + { + throw new IllegalStateException("No transaction in progress"); + } + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#isActive() + */ + @Override + public boolean isActive() + { + return (coordinator != null && coordinator.isTransactionActive()); + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#rollback() + */ + @Override + public void rollback() + { + onTransaction(TxAction.ROLLBACK); + ((EntityManagerImpl) entityManager).getPersistenceDelegator().rollback(); + } + + private void onTransaction(TxAction action) + { + if (isActive()) + { + coordinator.coordinate(action); + } + else + { + throw new IllegalStateException("No transaction in progress"); + } + } + + /* + * (non-Javadoc) + * + * @see javax.persistence.EntityTransaction#setRollbackOnly() + */ + @Override + public void setRollbackOnly() + { + this.rollbackOnly = true; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaTransactionException.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaTransactionException.java new file mode 100644 index 000000000..0e70acd61 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/KunderaTransactionException.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh + * + */ +public class KunderaTransactionException extends KunderaException +{ + + /** + * + */ + private static final long serialVersionUID = -7672192031279208722L; + + /** + * + */ + public KunderaTransactionException() + { + } + + /** + * @param arg0 + */ + public KunderaTransactionException(String arg0) + { + super(arg0); + } + + /** + * @param arg0 + */ + public KunderaTransactionException(Throwable arg0) + { + super(arg0); + } + + /** + * @param arg0 + * @param arg1 + */ + public KunderaTransactionException(String arg0, Throwable arg1) + { + super(arg0, arg1); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceDelegator.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceDelegator.java new file mode 100644 index 000000000..079ade4c4 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceDelegator.java @@ -0,0 +1,984 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import javax.persistence.FlushModeType; +import javax.persistence.Query; +import javax.persistence.metamodel.Metamodel; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.impetus.kundera.client.ClientResolverException; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.ObjectGraph; +import com.impetus.kundera.graph.ObjectGraphBuilder; +import com.impetus.kundera.graph.ObjectGraphUtils; +import com.impetus.kundera.lifecycle.states.ManagedState; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.lifecycle.states.TransientState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.IdDiscriptor; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.EventLog.EventType; +import com.impetus.kundera.persistence.context.FlushManager; +import com.impetus.kundera.persistence.context.MainCache; +import com.impetus.kundera.persistence.context.PersistenceCache; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.persistence.context.jointable.JoinTableData.OPERATION; +import com.impetus.kundera.persistence.event.EntityEventDispatcher; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.proxy.LazyInitializerFactory; +import com.impetus.kundera.query.QueryResolver; +import com.impetus.kundera.utils.ObjectUtils; + +/** + * The Class PersistenceDelegator. + */ +public final class PersistenceDelegator +{ + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(PersistenceDelegator.class); + + /** The closed. */ + private boolean closed; + + /** The client map. */ + private Map clientMap = new HashMap(); + + /** The event dispatcher. */ + private EntityEventDispatcher eventDispatcher; + + // /** The is relation via join table. */ + // private boolean isRelationViaJoinTable; + + private FlushModeType flushMode = FlushModeType.AUTO; + + private ObjectGraphBuilder graphBuilder; + + private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + // Whether a transaction is in progress + private boolean isTransactionInProgress; + + private PersistenceCache persistenceCache; + + private FlushManager flushManager = new FlushManager(); + + private boolean enableFlush; + + private Coordinator coordinator; + + /** + * Instantiates a new persistence delegator. + * + * @param session + * the session + * @param persistenceUnits + * the persistence units + */ + PersistenceDelegator(final PersistenceCache pc) + { + this.eventDispatcher = new EntityEventDispatcher(); + this.graphBuilder = new ObjectGraphBuilder(pc, this); + this.persistenceCache = pc; + } + + /***********************************************************************/ + /***************** CRUD Methods ****************************************/ + /***********************************************************************/ + + /** + * Writes an entity into Persistence cache. (Actual database write is done + * while flushing) + */ + public void persist(Object e) + { + if (e == null) + { + throw new IllegalArgumentException( + "Entity object is invalid, operation failed. Please check previous log message for details"); + } + EntityMetadata metadata = getMetadata(e.getClass()); + + // Create an object graph of the entity object. + ObjectGraph graph = graphBuilder.getObjectGraph(e, new TransientState()); + + // Call persist on each node in object graph. + Node node = graph.getHeadNode(); + try + { + // Get write lock before writing object required for transaction. + lock.writeLock().lock(); + + node.persist(); + + // build flush stack. + flushManager.buildFlushStack(node, com.impetus.kundera.persistence.context.EventLog.EventType.INSERT); + + // Flushing data. + flush(); + + // Update Primary key into entity class in case it is generated by + // database + // updateId(e, metadata, node); + + // Add node to persistence context after successful flush. + getPersistenceCache().getMainCache().addHeadNode(node); + } + finally + { + lock.writeLock().unlock(); + } + + // Unlocking object. + graph.clear(); + graph = null; + if (log.isDebugEnabled()) + { + log.debug("Data persisted successfully for entity : " + e.getClass()); + } + } + + /** + * Updates id of user entity object. + * + * @param e + * @param metadata + * @param node + */ + private void updateId(Object e, EntityMetadata metadata, Node node) + { + Metamodel metamodel = KunderaMetadataManager.getMetamodel(metadata.getPersistenceUnit()); + IdDiscriptor keyValue = ((MetamodelImpl) metamodel).getKeyValue(e.getClass().getName()); + if (keyValue != null) + { + + PropertyAccessorHelper.setId(e, metadata, node.getEntityId()); + for (Relation relation : metadata.getRelations()) + { + Object relObj = PropertyAccessorHelper.getObject(e, relation.getProperty()); + if (node.getEntityId().getClass().isAssignableFrom(int.class) + && e.hashCode() != (Integer) node.getEntityId()) + { + if (relation.isUnary()) + { + updateRecursively(relation, relObj); + } + else if (relation.isCollection()) + { + Collection col = (Collection) relObj; + for (Object obj : col) + { + updateRecursively(relation, obj); + } + } + } + } + + } + } + + private void updateRecursively(Relation relation, Object obj) + { + if (obj != null) + { + + Node relNode = getPersistenceCache().getMainCache().getNodeFromCache(obj); + if (relNode != null) + { + EntityMetadata relMetadata = getMetadata(relation.getTargetEntity()); + updateId(obj, relMetadata, relNode); + } + } + } + + /** + * Find object based on primary key either form persistence cache or from + * database + * + * @param entityClass + * @param primaryKey + * @return + */ + public E findById(Class entityClass, Object primaryKey) + { + E e = find(entityClass, primaryKey); + if (e == null) + return null; + + // I don't it's needed as already done via find () method! + /* + * // Set this returned entity as head node if applicable String nodeId + * = ObjectGraphUtils.getNodeId(primaryKey, entityClass); CacheBase + * mainCache = getPersistenceCache().getMainCache(); Node node = + * mainCache.getNodeFromCache(nodeId); if (node != null && + * node.getParents() == null && + * !mainCache.getHeadNodes().contains(node)) { + * mainCache.addHeadNode(node); } + */ + // Return a copy of this entity + return (E) (e); + } + + /** + * Finds an entity from persistence cache, if not there, fetches from + * database. Nodes are added into persistence cache (if not already there) + * as and when they are found from DB. While adding nodes to persistence + * cache, a deep copy is added, so that found object doesn't refer to + * managed entity in persistence cache. + * + * @param entityClass + * Entity Class + * @param primaryKey + * Primary Key + * @return Entity Object for the given primary key + * + */ + E find(Class entityClass, Object primaryKey) + { + if (primaryKey == null) + { + throw new IllegalArgumentException("PrimaryKey value must not be null for object you want to find."); + } + // Locking as it might read from persistence context. + + EntityMetadata entityMetadata = getMetadata(entityClass); + + String nodeId = ObjectGraphUtils.getNodeId(primaryKey, entityClass); + + // TODO all the scrap should go from here. + MainCache mainCache = (MainCache) getPersistenceCache().getMainCache(); + Node node = mainCache.getNodeFromCache(nodeId); + + // if node is not in persistence cache or is dirty, fetch from database + if (node == null || node.isDirty()) + { + node = new Node(nodeId, entityClass, new ManagedState(), getPersistenceCache(), primaryKey); + node.setClient(getClient(entityMetadata)); + // TODO ManagedState.java require serious attention. + node.setPersistenceDelegator(this); + + try + { + lock.readLock().lock(); + node.find(); + } + finally + { + lock.readLock().unlock(); + } + } + Object nodeData = node.getData(); + if (nodeData == null) + { + return null; + } + else + { + E e = (E) ObjectUtils.deepCopy(nodeData); + + onSetProxyOwners(entityMetadata,e); + return e; + } + + } + + /** + * Retrieves a {@link List} of Entities for given Primary Keys + * + * @param entityClass + * Entity Class + * @param primaryKeys + * Array of Primary Keys + * @see {@link PersistenceDelegator#find(Class, Object)} + * @return List of found entities + */ + // TODO Is it possible to pass all primary keys directly to database client. + public List find(Class entityClass, Object... primaryKeys) + { + List entities = new ArrayList(); + if (primaryKeys == null) + { + return entities; + } + Set pKeys = new HashSet(Arrays.asList(primaryKeys)); + for (Object primaryKey : pKeys) + { + E e = find(entityClass, primaryKey); + if (e != null) + entities.add(e); + } + return entities; + } + + /** + * Retrieves {@link List} of entities for a given {@link Map} of embedded + * column values. Purpose of this method is to provide functionality of + * search based on columns inside embedded objects. + * + * @param entityClass + * Entity Class + * @param embeddedColumnMap + * Embedded column map values + * @return List of found entities. + */ + public List find(Class entityClass, Map embeddedColumnMap) + { + EntityMetadata entityMetadata = getMetadata(entityClass); + + // TODO Why returning entities are not added into cache we should not + // iterate here but client should i think. + List entities = new ArrayList(); + entities = getClient(entityMetadata).find(entityClass, embeddedColumnMap); + + return entities; + } + + /** + * Removes an entity object from persistence cache. + * + */ + public void remove(Object e) + { + // Invoke Pre Remove Events + + // TODO Check for validity also as per JPA + if (e == null) + { + throw new IllegalArgumentException("Entity to be removed must not be null."); + } + + EntityMetadata metadata = getMetadata(e.getClass()); + + // Create an object graph of the entity object + ObjectGraph graph = graphBuilder.getObjectGraph(e, new ManagedState()); + + Node node = graph.getHeadNode(); + + try + { + lock.writeLock().lock(); + + // TODO : push into action queue, get original end-point from + // persistenceContext first! + + // Action/ExecutionQueue/ActivityQueue :-> id, name, EndPoint, + // changed + // state + + // Change state of node, after successful flush processing. + node.remove(); + + // build flush stack. + + flushManager.buildFlushStack(node, EventType.DELETE); + + // Flush node. + flush(); + } + finally + { + lock.writeLock().unlock(); + } + // clear out graph + graph.clear(); + graph = null; + + if (log.isDebugEnabled()) + log.debug("Data removed successfully for entity : " + e.getClass()); + } + + /** + * Flushes Dirty objects in {@link PersistenceCache} to databases. + * + */ + private void flush() + { + // Get flush stack from Flush Manager + Deque fs = flushManager.getFlushStack(); + + // Flush each node in flush stack from top to bottom unit it's empty + + if (log.isDebugEnabled()) + { + log.debug("Flushing following flush stack to database(s) (showing stack objects from top to bottom):\n" + + fs); + } + if (fs != null) + { + boolean isBatch = false; + while (!fs.isEmpty()) + { + Node node = fs.pop(); + + // Only nodes in Managed and Removed state are flushed, rest + // are ignored + if (node.isInState(ManagedState.class) || node.isInState(RemovedState.class)) + { + EntityMetadata metadata = getMetadata(node.getDataClass()); + node.setClient(getClient(metadata)); + + // if batch size is defined. + if ((node.getClient() instanceof Batcher) && ((Batcher) (node.getClient())).getBatchSize() > 0) + { + isBatch = true; + ((Batcher) (node.getClient())).addBatch(node); + } + else if (isTransactionInProgress + && MetadataUtils.defaultTransactionSupported(metadata.getPersistenceUnit())) + { + onSynchronization(node, metadata); + } + else + { + node.flush(); + } + } + + } + + if (!isBatch) + { + // TODO : This needs to be look for different + // permutation/combination + // Flush Join Table data into database + flushJoinTableData(); + // performed, + } + } + } + + public E merge(E e) + { + if (log.isDebugEnabled()) + log.debug("Merging Entity : " + e); + + if (e == null) + { + throw new IllegalArgumentException("Entity to be merged must not be null."); + } + + EntityMetadata m = getMetadata(e.getClass()); + + // Create an object graph of the entity object to be merged + ObjectGraph graph = graphBuilder.getObjectGraph(e, new ManagedState()); + + // Call merge on each node in object graph + Node node = graph.getHeadNode(); + + try + { + lock.writeLock().lock(); + // Change node's state after successful flush. + + // TODO : push into action queue, get original end-point from + // persistenceContext first! + + // Action/ExecutionQueue/ActivityQueue :-> id, name, EndPoint, + // changed + // state + + node.merge(); + + // build flush stack. + + flushManager.buildFlushStack(node, EventType.UPDATE); + + flush(); + } + finally + { + lock.writeLock().unlock(); + } + graph.clear(); + graph = null; + + return (E) node.getData(); + } + + /** + * Remove the given entity from the persistence context, causing a managed + * entity to become detached. + */ + public void detach(Object entity) + { + Node node = getPersistenceCache().getMainCache().getNodeFromCache(entity); + if (node != null) + { + node.detach(); + } + } + + /** + * Gets the client. + * + * @param m + * the m + * @return the client + */ + public Client getClient(EntityMetadata m) + { + // // Persistence Unit used to retrieve client + if (m == null) + { + throw new KunderaException("Entitymatadata should not be null"); + } + String persistenceUnit = m.getPersistenceUnit(); + + Client client = clientMap.get(persistenceUnit); + if (client == null) + { + throw new ClientResolverException("No client configured for persistenceUnit" + persistenceUnit); + } + return client; + } + + /** + * Gets the event dispatcher. + * + * @return the event dispatcher + */ + public EntityEventDispatcher getEventDispatcher() + { + return eventDispatcher; + } + + /** + * Creates the query. + * + * @param jpaQuery + * the jpa query + * @return the query + */ + Query createQuery(String jpaQuery) + { + Query query = new QueryResolver().getQueryImplementation(jpaQuery, this); + return query; + } + + /** + * Checks if is open. + * + * @return true, if is open + */ + public boolean isOpen() + { + return !closed; + } + + /** + * Close. + */ + void close() + { + doFlush(); + eventDispatcher = null; + + // Close all clients created in this session + if (clientMap != null && !clientMap.isEmpty()) + { + for (Client client : clientMap.values()) + { + client.close(); + } + clientMap.clear(); + clientMap = null; + } + + onClearProxy(); + + // TODO: Move all nodes tied to this EM into detached state, need to + // discuss with Amresh. + + closed = true; + } + + private void onClearProxy() + { + if (KunderaMetadata.INSTANCE.getCoreMetadata() != null) + { + LazyInitializerFactory lazyInitializerrFactory = KunderaMetadata.INSTANCE.getCoreMetadata() + .getLazyInitializerFactory(); + + if (lazyInitializerrFactory != null) + { + lazyInitializerrFactory.clearProxies(); + } + } + } + + private void onSetProxyOwners(final EntityMetadata m,Object e) + { + if (KunderaMetadata.INSTANCE.getCoreMetadata() != null) + { + LazyInitializerFactory lazyInitializerrFactory = KunderaMetadata.INSTANCE.getCoreMetadata() + .getLazyInitializerFactory(); + + if (lazyInitializerrFactory != null) + { + lazyInitializerrFactory.setProxyOwners(m, e); + } + } + } + + void clear() + { + // Move all nodes tied to this EM into detached state + flushManager.clearFlushStack(); + getPersistenceCache().clean(); + onClearProxy(); + } + + /** + * Check if the instance is a managed entity instance belonging to the + * current persistence context. + */ + boolean contains(Object entity) + { + Node node = getPersistenceCache().getMainCache().getNodeFromCache(entity); + return node != null && node.isInState(ManagedState.class); + } + + /** + * Refresh the state of the instance from the database, overwriting changes + * made to the entity, if any. + */ + public void refresh(Object entity) + { + if (contains(entity)) + { + MainCache mainCache = (MainCache) getPersistenceCache().getMainCache(); + Node node = mainCache.getNodeFromCache(entity); + // Locking as it might read from persistence context. + + try + { + lock.readLock().lock(); + node.refresh(); + } + finally + { + lock.readLock().unlock(); + } + } + else + { + throw new IllegalArgumentException("This is not a valid or managed entity, can't be refreshed"); + } + } + + /** + * Gets the metadata. + * + * @param clazz + * the clazz + * @return the metadata + */ + private EntityMetadata getMetadata(Class clazz) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(clazz); + if (metadata == null) + { + throw new KunderaException("Entitymatadata should not be null"); + } + return metadata; + } + + /** + * @param flushMode + * the flushMode to set + */ + void setFlushMode(FlushModeType flushMode) + { + // TODO keeping it open for future releases current not using any where. + this.flushMode = flushMode; + } + + /** + * @return the isTransactionInProgress + */ + public boolean isTransactionInProgress() + { + return isTransactionInProgress; + } + + /** + * @return the persistenceCache + */ + public PersistenceCache getPersistenceCache() + { + return persistenceCache; + } + + /******************************* Transaction related methods ***********************************************/ + + void begin() + { + isTransactionInProgress = true; + } + + void commit() + { + enableFlush = true; + execute(); + flushManager.commit(); + flushManager.clearFlushStack(); + isTransactionInProgress = false; + enableFlush = false; + } + + /** + * On explicit call from em.flush(). + */ + void doFlush() + { + enableFlush = true; + flush(); + execute(); + enableFlush = false; + flushManager.commit(); + flushManager.clearFlushStack(); + } + + void rollback() + { + flushManager.rollback(this); + flushManager.clearFlushStack(); + getPersistenceCache().clean(); + isTransactionInProgress = false; + } + + /** + * Populates client specific properties. + * + * @param properties + * map of properties. + */ + void populateClientProperties(Map properties) + { + if (properties != null && !properties.isEmpty()) + { + Map clientMap = getDelegate(); + if (clientMap != null && !clientMap.isEmpty()) + { + // TODO If we have two pu for same client then? Need to discuss + // with Amresh. + for (Client client : clientMap.values()) + { + if (client instanceof ClientPropertiesSetter) + { + ClientPropertiesSetter cps = (ClientPropertiesSetter) client; + cps.populateClientProperties(client, properties); + } + } + } + } + else + { + if (log.isDebugEnabled()) + { + log.debug("Can't set Client properties as None/ Null was supplied"); + } + } + } + + /** + * Pre load client specific to persistence unit. + * + * @param persistenceUnit + * persistence unit. + * @param client + */ + + void loadClient(String persistenceUnit, Client client) + { + if (!clientMap.containsKey(persistenceUnit)) + { + clientMap.put(persistenceUnit, client); + } + } + + /** + * Returns map of client as delegate to entity manager. + * + * @return clientMap client map + */ + Map getDelegate() + { + return clientMap; + } + + /** + * Executes batch. + */ + private void execute() + { + if (clientMap != null) + { + for (Client client : clientMap.values()) + { + if (client instanceof Batcher) + { + // if no batch operation performed{may be running in transaction?} + if (((Batcher) client).getBatchSize() == 0 || ((Batcher) client).executeBatch() > 0) + { + flushJoinTableData(); + } + } + } + } + } + + /** + * On flushing join table data + */ + private void flushJoinTableData() + { + if (applyFlush()) + { + for (JoinTableData jtData : flushManager.getJoinTableData()) + { + if (!jtData.isProcessed()) + { + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(jtData.getEntityClass()); + Client client = getClient(m); + if (OPERATION.INSERT.equals(jtData.getOperation())) + { + client.persistJoinTable(jtData); + jtData.setProcessed(true); + } + else if (OPERATION.DELETE.equals(jtData.getOperation())) + { + for (Object pk : jtData.getJoinTableRecords().keySet()) + { + client.deleteByColumn(m.getSchema(), jtData.getJoinTableName(), + ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(), pk); + } + jtData.setProcessed(true); + } + } + + } + } + } + + /** + * Returns true, if flush mode is AUTO and not running within transaction || + * running within transaction and commit is invoked. + * + * @return boolean value. + */ + private boolean applyFlush() + { + return (!isTransactionInProgress && flushMode.equals(FlushModeType.AUTO)) || enableFlush; + } + + /** + * Returns transaction coordinator. + * + * @return + */ + Coordinator getCoordinator() + { + coordinator = new Coordinator(); + try + { + for (String pu : clientMap.keySet()) + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(pu); + + String txResource = puMetadata.getProperty(PersistenceProperties.KUNDERA_TRANSACTION_RESOURCE); + + if (txResource != null) + { + TransactionResource resource = (TransactionResource) Class.forName(txResource).newInstance(); + coordinator.addResource(resource, pu); + Client client = clientMap.get(pu); + + if (!(client instanceof TransactionBinder)) + { + throw new KunderaTransactionException( + "Client : " + + client.getClass() + + " must implement TransactionBinder interface, if {kundera.transaction.resource.class} property provided!"); + } + else + { + ((TransactionBinder) client).bind(resource); + } + } + else + { + coordinator.addResource(new DefaultTransactionResource(clientMap.get(pu)), pu); + } + } + } catch(Exception e) + { + log.error("Error while initializing Transaction Resource:", e); + throw new KunderaTransactionException(e); + + } + + return coordinator; + } + + /** + * If transaction is in progress and user explicitly invokes em.flush()! + * + * @param node + * data node + * @param metadata + * entity metadata. + */ + private void onSynchronization(Node node, EntityMetadata metadata) + { + DefaultTransactionResource resource = (DefaultTransactionResource) coordinator.getResource(metadata + .getPersistenceUnit()); + if (enableFlush) + { + resource.onFlush(); + } + else + { + resource.syncNode(node); + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceValidator.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceValidator.java new file mode 100644 index 000000000..21e2e38d1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/PersistenceValidator.java @@ -0,0 +1,61 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * Responsible for validating entity persistence + * + * @author amresh.singh + */ +public class PersistenceValidator +{ + private static final Logger log = LoggerFactory.getLogger(PersistenceValidator.class); + + /** + * Validates an entity object for CRUD operations + * + * @param entity + * Instance of entity object + * @return True if entity object is valid, false otherwise + */ + public boolean isValidEntityObject(Object entity) + { + if (entity == null) + { + log.error("Entity to be persisted must not be null, operation failed"); + return false; + } + + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + + Object id = PropertyAccessorHelper.getId(entity, metadata); + if (id == null) + { + log.error("Entity to be persisted can't have Primary key set to null."); + return false; + } + return true; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/ResourceManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/ResourceManager.java new file mode 100644 index 000000000..4cd690210 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/ResourceManager.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +/** + * The Interface ResourceManager. + * + * @author vivek.mishra + */ +public interface ResourceManager +{ + + /** + * Do commit. + */ + void doCommit(); + + /** + * Do rollback. + */ + void doRollback(); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionBinder.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionBinder.java new file mode 100644 index 000000000..f95737a1c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionBinder.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence; + +/** + * TransactionBinder interface. If underlying database provides in-built + * transaction support, client has to implement this interface and bind + * transaction resource with client. + * + * @author vivek.mishra + * + */ +public interface TransactionBinder +{ + + /** + * Binds a transaction resource with client instance. Any subsequent CRUD + * calls will use this transaction resource to mark bind within already + * running transaction boundary. TransactionResource is responsible to bind + * and provide connection instance with for subsequent commit/rollback. + * + * @param resource + * transactional resource + */ + void bind(TransactionResource resource); +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionResource.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionResource.java new file mode 100644 index 000000000..8512fa30f --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/TransactionResource.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence; + +/** + * TransactionResource interface will delegate begin/commit/rollback to client + * and each client will implement this interface provided transaction support is + * required for corresponding database. If underlying database supports + * transaction then it will + * + * @author vivek.mishra + * + */ +public interface TransactionResource +{ + + /** + * On begin transactions. + */ + void onBegin(); + + /** + * On commit transactions. + */ + void onCommit(); + + /** + * On rollback transactions. + */ + void onRollback(); + + /** + * On intermediate flush, when explicitly flush is invoked by em.flush()! + */ + void onFlush(); + + /** + * On prepare for two phase commit. + * + * @return response, returns YES if it is ready for commit + */ + Response prepare(); + + /** + * Returns true if transaction is active else false. + * + * @return boolean true. + */ + boolean isActive(); + + /** + * + * Response enum + * + */ + enum Response + { + YES, NO; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/api/Batcher.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/api/Batcher.java new file mode 100644 index 000000000..9cee2df7d --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/api/Batcher.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.api; + +import com.impetus.kundera.graph.Node; + +/** + * API to handler batch operations. + * + * @author vivek.mishra + * + */ +public interface Batcher +{ + + /** + * Adds node to batch collection. + * + * @param node + * data node. + */ + void addBatch(Node node); + + /** + * executes batch. + * + * @return returns number of records persisted/update via batch. + */ + int executeBatch(); + + /** + * Returns batch size + * + * @return batch size as integer + */ + int getBatchSize(); + + /** + * In case user asked for + */ + void clear(); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/CacheBase.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/CacheBase.java new file mode 100644 index 000000000..6ff198cd1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/CacheBase.java @@ -0,0 +1,194 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.NodeLink; +import com.impetus.kundera.graph.ObjectGraph; +import com.impetus.kundera.graph.ObjectGraphUtils; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ObjectUtils; + +/** + * Base class for all cache required in persistence context + * + * @author amresh.singh + */ +public class CacheBase { + private static Logger log = LoggerFactory.getLogger(CacheBase.class); + + private Map nodeMappings; + + private Set headNodes; + + public CacheBase() { + headNodes = new HashSet(); + nodeMappings = new HashMap(); + } + + public Node getNodeFromCache(String nodeId) { + Node node = nodeMappings.get(nodeId); + return node; + } + + public Node getNodeFromCache(Object entity) { + if (entity == null) { + throw new IllegalArgumentException("Entity is null, can't check whether it's in persistence context"); + } + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + Object primaryKey = PropertyAccessorHelper.getId(entity, entityMetadata); + + if (primaryKey == null) { + throw new IllegalArgumentException("Primary key not set into entity"); + } + String nodeId = ObjectGraphUtils.getNodeId(primaryKey, entity.getClass()); + return getNodeFromCache(nodeId); + } + + public void addNodeToCache(Node node) { + // Make a deep copy of Node data and and set into node + // Original data object is now detached from Node and is possibly + // referred by user code + Object nodeDataCopy = ObjectUtils.deepCopy(node.getData()); + node.setData(nodeDataCopy); + + /* + * check if this node already exists in cache node mappings If yes, update parents and children links Otherwise, + * just simply add the node to cache node mappings + */ + + processNodeMapping(node); + } + + public void processNodeMapping(Node node) { + if (nodeMappings.containsKey(node.getNodeId())) { + Node existingNode = nodeMappings.get(node.getNodeId()); + + if (existingNode.getParents() != null) { + if (node.getParents() == null) { + node.setParents(new HashMap()); + } + node.getParents().putAll(existingNode.getParents()); + } + + if (existingNode.getChildren() != null) { + if (node.getChildren() == null) { + node.setChildren(new HashMap()); + } + node.getChildren().putAll(existingNode.getChildren()); + } + + nodeMappings.put(node.getNodeId(), node); + logCacheEvent("ADDED TO ", node.getNodeId()); + } else { + logCacheEvent("ADDED TO ", node.getNodeId()); + nodeMappings.put(node.getNodeId(), node); + } + + // If it's a head node, add this to the list of head nodes in + // Persistence Cache + if (node.isHeadNode()) { + node.getPersistenceCache().getMainCache().addHeadNode(node); + } + } + + public void removeNodeFromCache(Node node) { + if (getHeadNodes().contains(node)) { + getHeadNodes().remove(node); + } + + if (nodeMappings.get(node.getNodeId()) != null) { + nodeMappings.remove(node.getNodeId()); + } + + logCacheEvent("REMOVED FROM ", node.getNodeId()); + node = null; // Eligible for GC + } + + public void addGraphToCache(ObjectGraph graph, PersistenceCache persistenceCache) { + // Add each node in the graph to cache + for (String key : graph.getNodeMapping().keySet()) { + Node thisNode = graph.getNodeMapping().get(key); + addNodeToCache(thisNode); + + // Remove all those head nodes in persistence cache, that are there + // in Graph as a non-head node + if (!thisNode.isHeadNode() && persistenceCache.getMainCache().getHeadNodes().contains(thisNode)) { + persistenceCache.getMainCache().getHeadNodes().remove(thisNode); + } + } + // Add head Node to list of head nodes + addHeadNode(graph.getHeadNode()); + } + + private void logCacheEvent(String eventType, String nodeId) { + if (log.isDebugEnabled()) { + log.debug("Node: " + nodeId + ":: " + eventType + " Persistence Context"); + } + } + + /** + * @param nodeMappings + * the nodeMappings to set + */ + public void setNodeMappings(Map nodeMappings) { + this.nodeMappings = nodeMappings; + } + + /** + * @return the headNodes + */ + public Set getHeadNodes() { + return headNodes; + } + + public void addHeadNode(Node headNode) { + headNodes.add(headNode); + } + + public int size() { + return nodeMappings.size(); + } + + public Collection getAllNodes() { + return nodeMappings.values(); + } + + /** + * + */ + public void clear() { + this.nodeMappings.clear(); + this.headNodes.clear(); + this.nodeMappings=null; + this.headNodes=null; + nodeMappings = new HashMap(); + headNodes = new HashSet(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/ElementCollectionCache.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/ElementCollectionCache.java new file mode 100644 index 000000000..f30b3de02 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/ElementCollectionCache.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +/** + * + * + * @author amresh.singh + */ +public class ElementCollectionCache extends CacheBase +{ + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EmbeddedCache.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EmbeddedCache.java new file mode 100644 index 000000000..a5cf14d78 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EmbeddedCache.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +/** + * + * + * @author amresh.singh + */ +public class EmbeddedCache extends CacheBase +{ + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLog.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLog.java new file mode 100644 index 000000000..cf7d96ba0 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLog.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.context; + +import com.impetus.kundera.graph.Node; + +/** + * Logs CRUD events, + * + * @author vivek.mishra + * + */ +public class EventLog +{ + + private EventType eventType; + + private long timeinMillies; + + private Node node; + + EventLog(EventType eventType, Node transactional) + { + this.node = transactional; + this.eventType = eventType; + this.timeinMillies = System.currentTimeMillis(); + } + + Node getSavePointData() + { + return node.getOriginalNode(); + } + + /** + * @return the entityId + */ + Object getEntityId() + { + return node.getNodeId(); + } + + /** + * @return the eventType + */ + EventType getEventType() + { + return eventType; + } + + /** + * @return the timeinMillies + */ + long getTimeinMillies() + { + return timeinMillies; + } + + /** + * @return the node + */ + Node getNode() + { + return node; + } + + public enum EventType + { + INSERT, UPDATE, DELETE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLogQueue.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLogQueue.java new file mode 100644 index 000000000..c8169c763 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/EventLogQueue.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.context; + +import java.util.HashMap; +import java.util.Map; + +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.persistence.context.EventLog.EventType; + +/** + * The Class EventLogQueue. + * + * @author vivek.mishra + */ +class EventLogQueue +{ + + /** The insert events. */ + private Map insertEvents; + + /** The update events. */ + private Map updateEvents; + + /** The delete events. */ + private Map deleteEvents; + + /** + * On event. + * + * @param log + * the log + * @param eventType + * the event type + */ + void onEvent(EventLog log, EventType eventType) + { + + switch (eventType) + { + case INSERT: + + onInsert(log); + break; + + case UPDATE: + onUpdate(log); + break; + + case DELETE: + onDelete(log); + break; + + default: + + throw new KunderaException("Invalid event type:" + eventType); + } + + } + + /** + * On delete. + * + * @param log + * the log + */ + private void onDelete(EventLog log) + { + if (deleteEvents == null) + { + deleteEvents = new HashMap(); + ; + } + + deleteEvents.put(log.getEntityId(), log); + + } + + /** + * On update. + * + * @param log + * the log + */ + private void onUpdate(EventLog log) + { + if (updateEvents == null) + { + updateEvents = new HashMap(); + + } + + updateEvents.put(log.getEntityId(), log); + } + + /** + * On insert. + * + * @param log + * the log + */ + private void onInsert(EventLog log) + { + if (insertEvents == null) + { + insertEvents = new HashMap(); + } + + insertEvents.put(log.getEntityId(), log); + + } + + /** + * Clear. + */ + void clear() + { + if (this.insertEvents != null) + { + insertEvents.clear(); + insertEvents = null; + + } + if (this.updateEvents != null) + { + updateEvents.clear(); + updateEvents = null; + + } + if (this.deleteEvents != null) + { + deleteEvents.clear(); + deleteEvents = null; + + } + } + + /** + * Gets the insert events. + * + * @return the insert events + */ + Map getInsertEvents() + { + return insertEvents; + } + + /** + * Gets the update events. + * + * @return the update events + */ + Map getUpdateEvents() + { + return updateEvents; + } + + /** + * Gets the delete events. + * + * @return the delete events + */ + Map getDeleteEvents() + { + return deleteEvents; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/FlushManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/FlushManager.java new file mode 100644 index 000000000..8a5e48126 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/FlushManager.java @@ -0,0 +1,526 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.NodeLink; +import com.impetus.kundera.graph.NodeLink.LinkProperty; +import com.impetus.kundera.lifecycle.states.ManagedState; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.JoinTableMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.persistence.context.EventLog.EventType; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.persistence.context.jointable.JoinTableData.OPERATION; + +/** + * Provides utility methods for managing Flush Stack. + * + * @author amresh.singh + */ +public class FlushManager +{ + + /** + * Deque containing Nodes to be flushed Entities are always flushed from the + * start, there way to end until deque is empty. + */ + private Deque stackQueue; + + /** + * Map containing data required for inserting records for each join table. + * Key -> Name of Join Table Value -> records to be persisted in the join + * table + */ + private List joinTableDataCollection = new ArrayList(); + + /** The event log queue. */ + private EventLogQueue eventLogQueue = new EventLogQueue(); + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(FlushManager.class); + + /** + * Instantiates a new flush manager. + */ + public FlushManager() + { + stackQueue = new ArrayDeque(); + } + + /** + * Builds the flush stack. + * + * @param headNode + * the head node + * @param eventType + * the event type + */ + public void buildFlushStack(Node headNode, EventType eventType) + { + if (headNode != null) + { + headNode.setTraversed(false); + addNodesToFlushStack(headNode, eventType); + } + } + + /** + * Adds the nodes to flush stack. + * + * @param node + * the node + * @param eventType + * the event type + */ + private void addNodesToFlushStack(Node node, EventType eventType) + { + + Map children = node.getChildren(); + + // If this is a leaf node (not having any child, no need to go any + // deeper + if (children != null) + { + Map oneToOneChildren = new HashMap(); + Map oneToManyChildren = new HashMap(); + Map manyToOneChildren = new HashMap(); + Map manyToManyChildren = new HashMap(); + + for (NodeLink nodeLink : children.keySet()) + { + Relation.ForeignKey multiplicity = nodeLink.getMultiplicity(); + + switch (multiplicity) + { + case ONE_TO_ONE: + oneToOneChildren.put(nodeLink, children.get(nodeLink)); + break; + case ONE_TO_MANY: + oneToManyChildren.put(nodeLink, children.get(nodeLink)); + break; + case MANY_TO_ONE: + manyToOneChildren.put(nodeLink, children.get(nodeLink)); + break; + case MANY_TO_MANY: + manyToManyChildren.put(nodeLink, children.get(nodeLink)); + break; + } + + } + + // Process One-To-Many children + for (NodeLink nodeLink : oneToManyChildren.keySet()) + { + // Process child node Graph recursively first + Node childNode = children.get(nodeLink); + + if (childNode != null && !childNode.isTraversed()) + { + addNodesToFlushStack(childNode, eventType); + } + } + + // Process Many-To-Many children + for (NodeLink nodeLink : manyToManyChildren.keySet()) + { + if (!node.isTraversed() && !(Boolean) nodeLink.getLinkProperty(LinkProperty.IS_RELATED_VIA_JOIN_TABLE)) + { + // Push this node to stack + node.setTraversed(true); + stackQueue.push(node); + logEvent(node, eventType); + } + + Node childNode = children.get(nodeLink); + + if (childNode != null) + { + // Extract information required to be persisted into + // Join + // Table + if (node.isDirty() && !node.isTraversed()) + { + // M-2-M relation fields that are Set or List are joined + // by join table. + // M-2-M relation fields that are Map aren't joined by + // Join table + + JoinTableMetadata jtmd = (JoinTableMetadata) nodeLink + .getLinkProperty(LinkProperty.JOIN_TABLE_METADATA); + if (jtmd != null) + { + String joinColumnName = (String) jtmd.getJoinColumns().toArray()[0]; + String inverseJoinColumnName = (String) jtmd.getInverseJoinColumns().toArray()[0]; + Object entityId = node.getEntityId(); + Object childId = childNode.getEntityId(); + Set childValues = new HashSet(); + childValues.add(childId); + + OPERATION operation = null; + if (node.getCurrentNodeState().getClass().equals(ManagedState.class)) + { + operation = OPERATION.INSERT; + } + else if (node.getCurrentNodeState().getClass().equals(RemovedState.class)) + { + operation = OPERATION.DELETE; + } + + addJoinTableData(operation, jtmd.getJoinTableSchema(), jtmd.getJoinTableName(), + joinColumnName, inverseJoinColumnName, node.getDataClass(), entityId, childValues); + } + } + + // Process child node Graph recursively first + if (!childNode.isTraversed()) + { + addNodesToFlushStack(childNode, eventType); + } + } + } + // Process One-To-One children + for (NodeLink nodeLink : oneToOneChildren.keySet()) + { + if (!node.isTraversed()) + { + // Push this node to stack + node.setTraversed(true); + stackQueue.push(node); + logEvent(node, eventType); + } + + // Process child node Graph recursively + Node childNode = children.get(nodeLink); + + addNodesToFlushStack(childNode, eventType); + } + + // Process Many-To-One children + for (NodeLink nodeLink : manyToOneChildren.keySet()) + { + if (!node.isTraversed()) + { + // Push this node to stack + node.setTraversed(true); + stackQueue.push(node); + logEvent(node, eventType); + } + + // Child node of this node + Node childNode = children.get(nodeLink); + + // Process all parents of child node with Many-To-One + // relationship first + Map parents = childNode.getParents(); + for (NodeLink parentLink : parents.keySet()) + { + Relation.ForeignKey multiplicity = parentLink.getMultiplicity(); + if (multiplicity.equals(Relation.ForeignKey.MANY_TO_ONE)) + { + Node parentNode = parents.get(parentLink); + + if (!parentNode.isTraversed() && parentNode.isDirty()) + { + addNodesToFlushStack(parentNode, eventType); + } + } + } + + // Finally process this child node + if (!childNode.isTraversed() && childNode.isDirty()) + { + addNodesToFlushStack(childNode, eventType); + } + else if (!childNode.isDirty()) + { + childNode.setTraversed(true); + stackQueue.push(childNode); + logEvent(childNode, eventType); + } + } + } + + // Finally, if this node itself is not traversed yet, (as may happen + // in + // 1-1 and M-1 + // cases), push it to stack + if (!node.isTraversed() && node.isDirty()) + { + node.setTraversed(true); + stackQueue.push(node); + logEvent(node, eventType); + } + } + + /* *//** + * Gets the flush stack. + * + * @return the flushStack + */ + public Deque getFlushStack() + { + return stackQueue; + } + + /** + * Gets the join table data map. + * + * @return the joinTableDataMap + */ + public List getJoinTableData() + { + return joinTableDataCollection; + } + + /** + * Empties Flush stack present in a PersistenceCache. + * + */ + public void clearFlushStack() + { + if (stackQueue != null && !stackQueue.isEmpty()) + { + stackQueue.clear(); + } + if (joinTableDataCollection != null && !joinTableDataCollection.isEmpty()) + { + joinTableDataCollection.clear(); + joinTableDataCollection = null; + joinTableDataCollection = new ArrayList(); + } + + if (eventLogQueue != null) + { + eventLogQueue.clear(); + } + } + + /** + * Rollback. + * + * @param delegator + * the delegator + */ + public void rollback(PersistenceDelegator delegator) + { + if (eventLogQueue != null) + { + onRollBack(delegator, eventLogQueue.getInsertEvents()); + onRollBack(delegator, eventLogQueue.getUpdateEvents()); + onRollBack(delegator, eventLogQueue.getDeleteEvents()); + + rollbackJoinTableData(delegator); + } + } + + /** + * Rollback. + * + * @param delegator + * the delegator + */ + public void commit() + { + onCommit(eventLogQueue.getInsertEvents()); + onCommit(eventLogQueue.getUpdateEvents()); + onCommit(eventLogQueue.getDeleteEvents()); + } + + /** + * @param deleteEvents + */ + private void onCommit(Map eventCol) + { + if (eventCol != null && !eventCol.isEmpty()) + { + Collection events = eventCol.values(); + Iterator iter = events.iterator(); + + while (iter.hasNext()) + { + try + { + EventLog event = iter.next(); + Node node = event.getNode(); + if (node.isProcessed()) + { + // One time set as required for rollback. + Node original = node.clone(); + node.setOriginalNode(original); + } + + // mark it null for garbage collection. + event = null; + } + catch (Exception ex) + { + log.warn("Caught exception during rollback, Caused by:", ex); + // bypass to next event + } + + } + } + } + + /** + * On roll back. + * + * @param delegator + * the delegator + * @param eventCol + * the event col + */ + private void onRollBack(PersistenceDelegator delegator, Map eventCol) + { + if (eventCol != null && !eventCol.isEmpty()) + { + Collection events = eventCol.values(); + Iterator iter = events.iterator(); + + while (iter.hasNext()) + { + try + { + EventLog event = iter.next(); + Node node = event.getNode(); + Class clazz = node.getDataClass(); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(clazz); + Client client = delegator.getClient(metadata); + + // do manual rollback, if data is processed, and running + // without transaction or with kundera's default transaction + // support! + if (node.isProcessed() + && (!delegator.isTransactionInProgress() || MetadataUtils + .defaultTransactionSupported(metadata.getPersistenceUnit()))) + { + if (node.getOriginalNode() == null) + { + Object entityId = node.getEntityId(); + client.delete(node.getData(), entityId); + } + else + { + client.persist(node.getOriginalNode()); + } + } + // mark it null for garbage collection. + event = null; + } + catch (Exception ex) + { + log.warn("Caught exception during rollback, Caused by:", ex); + // bypass to next event + } + } + } + // mark it null for garbage collection. + eventCol = null; + } + + /** + * Adds the join table data into map. + * + * @param operation + * the operation + * @param joinTableName + * the join table name + * @param joinColumnName + * the join column name + * @param invJoinColumnName + * the inv join column name + * @param entityClass + * the entity class + * @param joinColumnValue + * the join column value + * @param invJoinColumnValues + * the inv join column values + */ + private void addJoinTableData(OPERATION operation, String schemaName, String joinTableName, String joinColumnName, + String invJoinColumnName, Class entityClass, Object joinColumnValue, Set invJoinColumnValues) + { + JoinTableData joinTableData = new JoinTableData(operation, schemaName, joinTableName, joinColumnName, + invJoinColumnName, entityClass); + joinTableData.addJoinTableRecord(joinColumnValue, invJoinColumnValues); + joinTableDataCollection.add(joinTableData); + } + + /** + * Log event. + * + * @param node + * the node + * @param eventType + * the event type + */ + private void logEvent(Node node, EventType eventType) + { + // Node contains original as well as transactional copy. + EventLog log = new EventLog(eventType, node); + eventLogQueue.onEvent(log, eventType); + } + + private void rollbackJoinTableData(PersistenceDelegator delegator) + { + // on deleting join table data. + for (JoinTableData jtData : joinTableDataCollection) + { + if (jtData.isProcessed()) + { + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(jtData.getEntityClass()); + Client client = delegator.getClient(m); + + if (OPERATION.INSERT.equals(jtData.getOperation())) + { + for (Object pk : jtData.getJoinTableRecords().keySet()) + { + client.deleteByColumn(jtData.getSchemaName(), jtData.getJoinTableName(), m.getIdAttribute() + .getName(), pk); + } + } + else if (OPERATION.DELETE.equals(jtData.getOperation())) + { + client.persistJoinTable(jtData); + } + } + } + joinTableDataCollection.clear(); + joinTableDataCollection = null; + joinTableDataCollection = new ArrayList(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/MainCache.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/MainCache.java new file mode 100644 index 000000000..25d19e778 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/MainCache.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +/** + * Main cache for the persistence context + * + * @author amresh.singh + */ +public class MainCache extends CacheBase +{ + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCache.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCache.java new file mode 100644 index 000000000..997442332 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCache.java @@ -0,0 +1,193 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +import javax.persistence.PersistenceContextType; + +/** + * Implementation of Persistence Context as defined in JPA. Acts as a cache of + * entities. + * + * @author amresh.singh + */ +public class PersistenceCache +{ + /* Main Cache of entity objects */ + private CacheBase mainCache; + + /* Cache of embedded objects */ + private CacheBase embeddedCache; + + /* Cache of objects within element collection */ + private CacheBase elementCollectionCache; + + /* Cache of transactional objects */ + private CacheBase transactionalCache; + + // FlushManager flushManager; + + private PersistenceContextType persistenceContextType; + + /** + * Stack containing Nodes to be flushed Entities are always flushed from the + * top, there way to bottom until stack is empty + */ + // private FlushStack flushStack; + + /** + * Map containing data required for inserting records for each join table. + * Key -> Name of Join Table Value -> records to be persisted in the join + * table + */ + // private Map joinTableDataMap; + + public PersistenceCache() + { + initialize(); + } + + private void initialize() + { + mainCache = new MainCache(); + embeddedCache = new EmbeddedCache(); + elementCollectionCache = new ElementCollectionCache(); + transactionalCache = new TransactionalCache(); + + // flushStack = new FlushStack(); + // joinTableDataMap = new HashMap(); + // + // flushManager = new FlushManager(); + } + + /** + * Cleaned out the data. + * + */ + public void clean() + { + // Clear main cache. + if (mainCache != null) + { + mainCache.clear(); + mainCache = null; + } + + if (embeddedCache != null) + { + embeddedCache.clear(); + embeddedCache = null; + } + if (elementCollectionCache != null) + { + elementCollectionCache.clear(); + elementCollectionCache = null; + } + if (transactionalCache != null) + { + transactionalCache.clear(); + transactionalCache = null; + } + + initialize(); + + } + + /** + * @return the mainCache + */ + public CacheBase getMainCache() + { + return mainCache; + } + + /** + * @param mainCache + * the mainCache to set + */ + public void setMainCache(CacheBase mainCache) + { + this.mainCache = mainCache; + } + + /** + * @return the embeddedCache + */ + public CacheBase getEmbeddedCache() + { + return embeddedCache; + } + + /** + * @param embeddedCache + * the embeddedCache to set + */ + public void setEmbeddedCache(CacheBase embeddedCache) + { + this.embeddedCache = embeddedCache; + } + + /** + * @return the elementCollectionCache + */ + public CacheBase getElementCollectionCache() + { + return elementCollectionCache; + } + + /** + * @param elementCollectionCache + * the elementCollectionCache to set + */ + public void setElementCollectionCache(CacheBase elementCollectionCache) + { + this.elementCollectionCache = elementCollectionCache; + } + + /** + * @return the transactionalCache + */ + public CacheBase getTransactionalCache() + { + return transactionalCache; + } + + /** + * @param transactionalCache + * the transactionalCache to set + */ + public void setTransactionalCache(CacheBase transactionalCache) + { + this.transactionalCache = transactionalCache; + } + + /** + * @return the persistenceContextType + */ + public PersistenceContextType getPersistenceContextType() + { + return persistenceContextType; + } + + /** + * @param persistenceContextType + * the persistenceContextType to set + */ + public void setPersistenceContextType(PersistenceContextType persistenceContextType) + { + this.persistenceContextType = persistenceContextType; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCacheManager.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCacheManager.java new file mode 100644 index 000000000..0c1a3e10f --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/PersistenceCacheManager.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.context; + +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.graph.ObjectGraphUtils; +import com.impetus.kundera.lifecycle.states.ManagedState; +import com.impetus.kundera.persistence.PersistenceDelegator; + +/** + * @author amresh + * + */ +public class PersistenceCacheManager +{ + private PersistenceCache persistenceCache; + + public PersistenceCacheManager(PersistenceCache pc) + { + this.persistenceCache = pc; + } + + public void clearPersistenceCache() + { + persistenceCache.clean(); + + } // cleanIndividualCache(pc.getMainCache()); + // cleanIndividualCache(pc.getEmbeddedCache()); + // cleanIndividualCache(pc.getElementCollectionCache()); + // cleanIndividualCache(pc.getTransactionalCache()); + + private void cleanIndividualCache(CacheBase cache) + { + for (Node node : cache.getAllNodes()) + { + node.clear(); + } + } + + public void markAllNodesNotTraversed() + { + for (Node node : persistenceCache.getMainCache().getAllNodes()) + { + node.setTraversed(false); + } + + for (Node node : persistenceCache.getEmbeddedCache().getAllNodes()) + { + node.setTraversed(false); + } + + for (Node node : persistenceCache.getElementCollectionCache().getAllNodes()) + { + node.setTraversed(false); + } + + for (Node node : persistenceCache.getTransactionalCache().getAllNodes()) + { + node.setTraversed(false); + } + } + + /** + * @param entity + * @param pd + * @param entityId + */ + public static void addEntityToPersistenceCache(Object entity, PersistenceDelegator pd, Object entityId) + { + MainCache mainCache = (MainCache) pd.getPersistenceCache().getMainCache(); + String nodeId = ObjectGraphUtils.getNodeId(entityId, entity.getClass()); + Node node = new Node(nodeId, entity.getClass(), new ManagedState(), pd.getPersistenceCache(), entityId); + node.setData(entity); + node.setPersistenceDelegator(pd); + mainCache.addNodeToCache(node); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/TransactionalCache.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/TransactionalCache.java new file mode 100644 index 000000000..07e3a788f --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/TransactionalCache.java @@ -0,0 +1,26 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context; + +/** + * + * + * @author amresh.singh + */ +public class TransactionalCache extends CacheBase +{ + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/jointable/JoinTableData.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/jointable/JoinTableData.java new file mode 100644 index 000000000..f2369bf8c --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/context/jointable/JoinTableData.java @@ -0,0 +1,219 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.persistence.context.jointable; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * Holds data required prior to persisting records in Join Table + * + * @author amresh.singh + */ +public class JoinTableData +{ + private String joinTableName; + + private String schemaName; + + private Class entityClass; + + private String joinColumnName; + + private String inverseJoinColumnName; + + private boolean isProcessed; + + public static enum OPERATION + { + INSERT, UPDATE, DELETE + } + + /** + * Operation to be performed on this Join Table data + * + * @See {@link OPERATION} + */ + private OPERATION operation; + + /** + * Key -> Primary key of entity at the Join column side Value -> Set of + * primary keys of entities at the inverse join column side + */ + Map> joinTableRecords; + + public JoinTableData(OPERATION operation, String schemaName, String joinTableName, String joinColumnName, + String inverseJoinColumnName, Class entityClass) + { + this.operation = operation; + this.schemaName = schemaName; + this.joinTableName = joinTableName; + this.joinColumnName = joinColumnName; + this.inverseJoinColumnName = inverseJoinColumnName; + this.entityClass = entityClass; + + joinTableRecords = new HashMap>(); + } + + /** + * @return the joinTableName + */ + public String getJoinTableName() + { + return joinTableName; + } + + /** + * @param joinTableName + * the joinTableName to set + */ + public void setJoinTableName(String joinTableName) + { + this.joinTableName = joinTableName; + } + + /** + * @return the joinColumnName + */ + public String getJoinColumnName() + { + return joinColumnName; + } + + /** + * @param joinColumnName + * the joinColumnName to set + */ + public void setJoinColumnName(String joinColumnName) + { + this.joinColumnName = joinColumnName; + } + + /** + * @return the inverseJoinColumnName + */ + public String getInverseJoinColumnName() + { + return inverseJoinColumnName; + } + + /** + * @param inverseJoinColumnName + * the inverseJoinColumnName to set + */ + public void setInverseJoinColumnName(String inverseJoinColumnName) + { + this.inverseJoinColumnName = inverseJoinColumnName; + } + + /** + * @return the joinTableRecords + */ + public Map> getJoinTableRecords() + { + return joinTableRecords; + } + + /** + * @return the entityClass + */ + public Class getEntityClass() + { + return entityClass; + } + + /** + * @param entityClass + * the entityClass to set + */ + public void setEntityClass(Class entityClass) + { + this.entityClass = entityClass; + } + + /** + * @return the operation + */ + public OPERATION getOperation() + { + return operation; + } + + /** + * @param operation + * the operation to set + */ + public void setOperation(OPERATION operation) + { + this.operation = operation; + } + + /** + * @param joinTableRecords + * the joinTableRecords to set + */ + public void addJoinTableRecord(Object key, Set values) + { + Set existingValues = joinTableRecords.get(key); + if (existingValues == null) + { + existingValues = new HashSet(); + existingValues.addAll(values); + joinTableRecords.put(key, existingValues); + } + else + { + existingValues.addAll(values); + } + } + + /** + * @return the isProcessed + */ + public boolean isProcessed() + { + return isProcessed; + } + + /** + * @param isProcessed + * the isProcessed to set + */ + public void setProcessed(boolean isProcessed) + { + this.isProcessed = isProcessed; + } + + /** + * @return the schemaName + */ + public String getSchemaName() + { + return schemaName; + } + + /** + * @param schemaName + * the schemaName to set + */ + public void setSchemaName(String schemaName) + { + this.schemaName = schemaName; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/CallbackMethod.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/CallbackMethod.java new file mode 100644 index 000000000..edd0400c1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/CallbackMethod.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.event; + +import java.lang.reflect.InvocationTargetException; + +/** + * Interface that defines how JPA Entity Listeners can be called. + * + * @author animesh.kumar + */ +public interface CallbackMethod +{ + + /** + * Invokes the method with entity object. + * + * @param entity + * the entity + * + * @throws IllegalArgumentException + * the illegal argument exception + * @throws IllegalAccessException + * the illegal access exception + * @throws InvocationTargetException + * the invocation target exception + * @throws InstantiationException + * the instantiation exception + */ + public void invoke(Object entity) throws EventListenerException; +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EntityEventDispatcher.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EntityEventDispatcher.java new file mode 100644 index 000000000..4a8fb1358 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EntityEventDispatcher.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.event; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The Class EntityEventDispatcher. + */ +public class EntityEventDispatcher +{ + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(EntityManager.class); + + /** + * Fire event listeners. + * + * @param metadata + * the metadata + * @param entity + * the entity + * @param event + * the event + * @throws PersistenceException + * the persistence exception + */ + public void fireEventListeners(EntityMetadata metadata, Object entity, Class event) + { + + // handle external listeners first + List callBackMethods = metadata.getCallbackMethods(event); + + if (null != callBackMethods && !callBackMethods.isEmpty()) + { + log.debug("Callback >> " + event.getSimpleName() + " on " + metadata.getEntityClazz().getName()); + for (CallbackMethod callback : callBackMethods) + { + log.debug("Firing >> " + callback); + + callback.invoke(entity); + + } + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EventListenerException.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EventListenerException.java new file mode 100644 index 000000000..58edba818 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/EventListenerException.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.event; + +import com.impetus.kundera.KunderaException; + +/** + * @author amresh + * + */ +public class EventListenerException extends KunderaException +{ + + /** + * + */ + public EventListenerException() + { + + } + + /** + * @param arg0 + */ + public EventListenerException(String arg0) + { + super(arg0); + } + + /** + * @param arg0 + */ + public EventListenerException(Throwable arg0) + { + super(arg0); + } + + /** + * @param arg0 + * @param arg1 + */ + public EventListenerException(String arg0, Throwable arg1) + { + super(arg0, arg1); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/ExternalCallbackMethod.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/ExternalCallbackMethod.java new file mode 100644 index 000000000..e0e5f755b --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/ExternalCallbackMethod.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.event; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Class to hold class-method instances for EntityListeners. + * + * @author animesh.kumar + */ +public final class ExternalCallbackMethod implements CallbackMethod +{ + + /** The clazz. */ + private Class clazz; + + /** The method. */ + private Method method; + + /** + * Instantiates a new external callback method. + * + * @param clazz + * the clazz + * @param method + * the method + */ + public ExternalCallbackMethod(Class clazz, Method method) + { + this.clazz = clazz; + this.method = method; + } + + public void invoke(Object entity) throws EventListenerException + { + if (!method.isAccessible()) + method.setAccessible(true); + try + { + method.invoke(clazz.newInstance(), new Object[] { entity }); + } + catch (IllegalArgumentException e) + { + throw new EventListenerException(e); + } + catch (IllegalAccessException e) + { + throw new EventListenerException(e); + } + catch (InvocationTargetException e) + { + throw new EventListenerException(e); + } + catch (InstantiationException e) + { + throw new EventListenerException(e); + } + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append(clazz.getName() + "." + method.getName()); + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/InternalCallbackMethod.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/InternalCallbackMethod.java new file mode 100644 index 000000000..4894be294 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/event/InternalCallbackMethod.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.event; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * The Class InternalCallbackMethod. + * + * @author animesh.kumar + */ +public final class InternalCallbackMethod implements CallbackMethod +{ + + /** The entity metadata. */ + private final EntityMetadata entityMetadata; + + /** The method. */ + private Method method; + + /** + * Instantiates a new internal callback method. + * + * @param entityMetadata + * TODO + * @param method + * the method + */ + public InternalCallbackMethod(EntityMetadata entityMetadata, Method method) + { + this.entityMetadata = entityMetadata; + this.method = method; + } + + /* + * @see + * com.impetus.kundera.ejb.event.CallbackMethod#invoke(java.lang.Object) + */ + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.ejb.event.CallbackMethod#invoke(java.lang.Object) + */ + public void invoke(Object entity) throws EventListenerException + { + if (!method.isAccessible()) + method.setAccessible(true); + try + { + method.invoke(entity, new Object[] {}); + } + catch (IllegalArgumentException e) + { + throw new EventListenerException(e); + } + catch (IllegalAccessException e) + { + throw new EventListenerException(e); + } + catch (InvocationTargetException e) + { + throw new EventListenerException(e); + } + } + + @Override + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append(this.entityMetadata.getEntityClazz().getName() + "." + method.getName()); + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaJTAUserTransaction.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaJTAUserTransaction.java new file mode 100644 index 000000000..e53fb5c05 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaJTAUserTransaction.java @@ -0,0 +1,273 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.jta; + +import java.io.Serializable; + +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.Referenceable; +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.NotSupportedException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.UserTransaction; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.persistence.ResourceManager; + +/** + * Kundera implementation for JTA UserTransaction + * + * This needs to hooked up with initial context for use of Kundera's + * commit/rollback handling. + * + * @author vivek.mishra@impetus.co.in + * + */ + +public class KunderaJTAUserTransaction implements UserTransaction, Referenceable, Serializable +{ + + /** The thread local. */ + private static transient ThreadLocal threadLocal = new ThreadLocal(); + + /** The timer thead. */ + private static transient ThreadLocal timerThead = new ThreadLocal(); + + /** The Constant DEFAULT_TIME_OUT. */ + private static final Integer DEFAULT_TIME_OUT = 60; + + /** The current tx. */ + private static transient KunderaJTAUserTransaction currentTx; + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(KunderaJTAUserTransaction.class); + + /** + * Instantiates a new kundera jta user transaction. + */ + public KunderaJTAUserTransaction() + { + currentTx = this; + } + + /** + * Gets the current tx. + * + * @return the current tx + */ + public static KunderaJTAUserTransaction getCurrentTx() + { + return currentTx; + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#begin() + */ + @Override + public void begin() throws NotSupportedException, SystemException + { + if (log.isDebugEnabled()) + log.info("beginning JTA transaction"); + + Transaction tx = threadLocal.get(); + if (tx != null) + { + if ((tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)) + { + throw new NotSupportedException("Nested Transaction not supported!"); + } + } + + Integer timer = timerThead.get(); + threadLocal.set(new KunderaTransaction(timer != null ? timer : DEFAULT_TIME_OUT)); + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#commit() + */ + @Override + public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, + SecurityException, IllegalStateException, SystemException + { + Transaction tx = threadLocal.get(); + + try + { + if (tx != null) + { + if (log.isDebugEnabled()) + log.info("Commiting transaction:" + tx); + tx.commit(); + } + else + { + log.debug("Cannot locate a transaction to commit."); + + } + } + finally + { + if (log.isDebugEnabled()) + log.info("Resetting after commit."); + threadLocal.set(null); + timerThead.set(null); + } + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#getStatus() + */ + @Override + public int getStatus() throws SystemException + { + Transaction tx = threadLocal.get(); + if (tx == null) + { + return Status.STATUS_NO_TRANSACTION; + } + return tx.getStatus(); + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#rollback() + */ + @Override + public void rollback() throws IllegalStateException, SecurityException, SystemException + { + + try + { + Transaction tx = threadLocal.get(); + if (tx == null) + { + throw new IllegalStateException("Cannot locate a Transaction for rollback."); + } + + if (log.isDebugEnabled()) + log.info("Rollback transaction:" + tx); + + tx.rollback(); + + } + finally + { + if (log.isDebugEnabled()) + log.info("Resetting after rollback."); + threadLocal.set(null); + timerThead.set(null); + } + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#setRollbackOnly() + */ + @Override + public void setRollbackOnly() throws IllegalStateException, SystemException + { + Transaction tx = threadLocal.get(); + if (tx == null) + { + throw new IllegalStateException("Cannot get Transaction for setRollbackOnly"); + } + tx.setRollbackOnly(); + + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.UserTransaction#setTransactionTimeout(int) + */ + @Override + public void setTransactionTimeout(int timeout) throws SystemException + { + Transaction tx = threadLocal.get(); + if (tx == null) + { + timerThead.set(timeout); + } + else + { + if (log.isDebugEnabled()) + log.debug("Cannot reset running transaction:" + tx); + } + + } + + /** + * Returns transaction time out. If no timeout is associate with current + * thread, returns default timeout(e.g. 60). + * + * @return the transactionTimeout transaction timeout. + */ + public int getTransactionTimeout() + { + Integer timeOut = timerThead.get(); + if (timeOut == null) + { + return DEFAULT_TIME_OUT; + } + return timeOut; + } + + /** + * Links referenced resource to current transaction thread. + * + * @param implementor + * resource implementor. + */ + public void setImplementor(ResourceManager implementor) + { + KunderaTransaction tx = threadLocal.get(); + if (tx == null) + { + throw new IllegalStateException("Cannot get Transaction to start"); + } + tx.setImplementor(implementor); + + } + + /* + * (non-Javadoc) + * + * @see javax.naming.Referenceable#getReference() + */ + @Override + public Reference getReference() throws NamingException + { + return UserTransactionFactory.getReference(this); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaTransaction.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaTransaction.java new file mode 100644 index 000000000..7da034f40 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/KunderaTransaction.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.persistence.jta; + +import java.util.HashSet; +import java.util.Set; + +import javax.transaction.HeuristicMixedException; +import javax.transaction.HeuristicRollbackException; +import javax.transaction.RollbackException; +import javax.transaction.Status; +import javax.transaction.Synchronization; +import javax.transaction.SystemException; +import javax.transaction.Transaction; +import javax.transaction.xa.XAResource; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.persistence.ResourceManager; + +/** + * Implementation for javax.transaction.Transaction + * + * @author vivek.mishra + * + */ +public class KunderaTransaction implements Transaction +{ + + private Set implementors = new HashSet(); + + private boolean setRollBackOnly; + + private int status = Status.STATUS_ACTIVE; + + /** The time out in millis. */ + private int timeOutInMillis; + + /** The Constant log. */ + private static final Logger log = LoggerFactory.getLogger(KunderaTransaction.class); + + /** + * Default constructor with timeout parameter. + */ + KunderaTransaction(int timeOutInMillis) + { + this.timeOutInMillis = timeOutInMillis; + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.Transaction#commit() + */ + @Override + public void commit() throws RollbackException, HeuristicMixedException, HeuristicRollbackException, + SecurityException, IllegalStateException, SystemException + { + if (!setRollBackOnly) + { + for (ResourceManager implementor : implementors) + { + if (implementor != null) + { + implementor.doCommit(); + } + } + status = Status.STATUS_COMMITTED; + } + else + { + if (log.isDebugEnabled()) + log.debug("Transaction is set for rollback only, processing rollback."); + + for (ResourceManager implementor : implementors) + { + if (implementor != null) + { + implementor.doRollback(); + status = Status.STATUS_ROLLEDBACK; + } + } + } + + } + + /* + * (non-Javadoc) + * + * @see + * javax.transaction.Transaction#delistResource(javax.transaction.xa.XAResource + * , int) + */ + @Override + public boolean delistResource(XAResource paramXAResource, int paramInt) throws IllegalStateException, + SystemException + { + // TODD: need to look into. + return false; + } + + /* + * (non-Javadoc) + * + * @see + * javax.transaction.Transaction#enlistResource(javax.transaction.xa.XAResource + * ) + */ + @Override + public boolean enlistResource(XAResource paramXAResource) throws RollbackException, IllegalStateException, + SystemException + { + // TODD: need to look into. + return false; + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.Transaction#getStatus() + */ + @Override + public int getStatus() throws SystemException + { + return status; + } + + /* + * (non-Javadoc) + * + * @see + * javax.transaction.Transaction#registerSynchronization(javax.transaction + * .Synchronization) + */ + @Override + public void registerSynchronization(Synchronization paramSynchronization) throws RollbackException, + IllegalStateException, SystemException + { + throw new UnsupportedOperationException("Currently it is not supported."); + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.Transaction#rollback() + */ + @Override + public void rollback() throws IllegalStateException, SystemException + { + for (ResourceManager implementor : implementors) + { + if (implementor != null) + { + implementor.doRollback(); + status = Status.STATUS_ROLLEDBACK; + } + } + } + + /* + * (non-Javadoc) + * + * @see javax.transaction.Transaction#setRollbackOnly() + */ + @Override + public void setRollbackOnly() throws IllegalStateException, SystemException + { + setRollBackOnly = true; + status = Status.STATUS_MARKED_ROLLBACK; + } + + void setImplementor(ResourceManager implementor) + { + implementors.add(implementor); + } + + /** + * @return the transactionTimeout + */ + public int getTransactionTimeout() + { + return timeOutInMillis; + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/UserTransactionFactory.java b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/UserTransactionFactory.java new file mode 100644 index 000000000..a4093ffe5 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/persistence/jta/UserTransactionFactory.java @@ -0,0 +1,103 @@ +/******************************************************************************* + + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.kundera.persistence.jta; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Hashtable; + +import javax.naming.BinaryRefAddr; +import javax.naming.Context; +import javax.naming.Name; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.spi.ObjectFactory; + +/** + * The factory for JNDI lookup of KunderaJTAUserTransaction + * objects. + * + * @author vivek.mishra@impetus.co.in + */ + +public class UserTransactionFactory implements ObjectFactory +{ + /** + * Default constructor. + */ + public UserTransactionFactory() + { + } + + /** + * Returns reference to userTransaction object. + * + * @see javax.naming.spi.ObjectFactory + */ + @Override + public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception + { + Reference ref = (Reference) obj; + Object ret = null; + + if (ref.getClassName().equals("javax.transaction.UserTransaction") + || ref.getClassName().equals("com.impetus.kundera.persistence.jta.KunderaJTAUserTransaction")) + { + ret = KunderaJTAUserTransaction.getCurrentTx(); + } + + if (ret == null) + { + ret = new KunderaJTAUserTransaction(); + } + return ret; + + } + + /** + * Method to return reference for serialized object.(i.e. + * KunderJTAUserTransaction) + * + * @param object + * serilized object. + * @return reference to that object. + * @throws NamingException + * naming exception. + */ + public static Reference getReference(Serializable object) throws NamingException + { + ByteArrayOutputStream outStream; + try + { + outStream = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(outStream); + out.writeObject(object); + out.close(); + } + catch (IOException e) + { + throw new NamingException(e.getMessage()); + } + + BinaryRefAddr handle = new BinaryRefAddr("com.impetus.kundera.persistence.jta", outStream.toByteArray()); + Reference ret = new Reference(object.getClass().getName(), handle, UserTransactionFactory.class.getName(), null); + return ret; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessException.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessException.java new file mode 100644 index 000000000..3d630e857 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessException.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property; + +import com.impetus.kundera.KunderaException; + +/** + * The Class PropertyAccessException. + * + * @author animesh.kumar + */ +public class PropertyAccessException extends KunderaException +{ + + /** The Constant serialVersionUID. */ + private static final long serialVersionUID = 2920598132353417557L; + + /** + * Instantiates a new property access exception. + */ + public PropertyAccessException() + { + } + + /** + * Instantiates a new property access exception. + * + * @param message + * the message + */ + public PropertyAccessException(String message) + { + super(message); + } + + /** + * Instantiates a new property access exception. + * + * @param cause + * the cause + */ + public PropertyAccessException(Throwable cause) + { + super(cause); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessor.java new file mode 100644 index 000000000..b965444ae --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessor.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property; + +import java.lang.reflect.Field; + +/** + * Interface to access {@link Field} property of a java class. + * + * @param + * the generic type + * @author animesh.kumar + */ +public interface PropertyAccessor +{ + + /** + * From bytes. + * + * @param b + * the b + * + * @return the T + * + * @throws PropertyAccessException + * the property access exception + */ + T fromBytes(Class targetClass, byte[] b); + + /** + * To bytes. + * + * @param object + * the object + * + * @return the byte[] + * + * @throws PropertyAccessException + * the property access exception + */ + byte[] toBytes(Object object); + + /** + * Converts Object to String. Normally, this will be object.toString() But + * in some cases, this might be different. + * + * @param object + * the object + * + * @return the string + */ + String toString(Object object); + + /** + * Converts string representation to the data object whose type is T. + * + * @param s + * the s + * @return the t + * @throws PropertyAccessException + * When string can't be converted to specified type, usually as + * a result of NumberFormatException + */ + T fromString(Class targetClass, String s); + + /** + * Gets copy of object + * + * @param object + * @return + */ + T getCopy(Object object); + + /** + * @param clazz + * + */ + Object getInstance(Class clazz); + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorFactory.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorFactory.java new file mode 100644 index 000000000..f88b84dbd --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorFactory.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.property.accessor.BigDecimalAccessor; +import com.impetus.kundera.property.accessor.BigIntegerAccessor; +import com.impetus.kundera.property.accessor.BooleanAccessor; +import com.impetus.kundera.property.accessor.ByteAccessor; +import com.impetus.kundera.property.accessor.CalendarAccessor; +import com.impetus.kundera.property.accessor.CharAccessor; +import com.impetus.kundera.property.accessor.DateAccessor; +import com.impetus.kundera.property.accessor.DoubleAccessor; +import com.impetus.kundera.property.accessor.EnumAccessor; +import com.impetus.kundera.property.accessor.FloatAccessor; +import com.impetus.kundera.property.accessor.IntegerAccessor; +import com.impetus.kundera.property.accessor.LongAccessor; +import com.impetus.kundera.property.accessor.ObjectAccessor; +import com.impetus.kundera.property.accessor.PointAccessor; +import com.impetus.kundera.property.accessor.SQLDateAccessor; +import com.impetus.kundera.property.accessor.SQLTimeAccessor; +import com.impetus.kundera.property.accessor.SQLTimestampAccessor; +import com.impetus.kundera.property.accessor.ShortAccessor; +import com.impetus.kundera.property.accessor.StringAccessor; +import com.impetus.kundera.property.accessor.UUIDAccessor; + +/** + * The Class PropertyAccessorFactory. + * + * @author animesh.kumar + */ + +public class PropertyAccessorFactory +{ + + /** The map. */ + public static Map, PropertyAccessor> map = new HashMap, PropertyAccessor>(); + + static + { + // Premitive Type accessors + map.put(boolean.class, new BooleanAccessor()); + map.put(byte.class, new ByteAccessor()); + map.put(short.class, new ShortAccessor()); + map.put(char.class, new CharAccessor()); + map.put(int.class, new IntegerAccessor()); + map.put(long.class, new LongAccessor()); + map.put(float.class, new FloatAccessor()); + map.put(double.class, new DoubleAccessor()); + + // Wrapper Object accessors + map.put(Boolean.class, new BooleanAccessor()); + map.put(Byte.class, new ByteAccessor()); + map.put(Short.class, new ShortAccessor()); + map.put(Character.class, new CharAccessor()); + map.put(Integer.class, new IntegerAccessor()); + map.put(Long.class, new LongAccessor()); + map.put(Float.class, new FloatAccessor()); + map.put(Double.class, new DoubleAccessor()); + + // Date/ Time type accessors + map.put(Date.class, new DateAccessor()); + map.put(java.sql.Date.class, new SQLDateAccessor()); + map.put(Time.class, new SQLTimeAccessor()); + map.put(Timestamp.class, new SQLTimestampAccessor()); + map.put(Calendar.class, new CalendarAccessor()); + map.put(GregorianCalendar.class, new CalendarAccessor()); + + // Accessors for Math classes + map.put(BigInteger.class, new BigIntegerAccessor()); + map.put(BigDecimal.class, new BigDecimalAccessor()); + + // String class Accessor + map.put(String.class, new StringAccessor()); + + // Accessor for the generic object + map.put(Object.class, new ObjectAccessor()); + + // Accessor for Enum types + map.put(Enum.class, new EnumAccessor()); + + map.put(UUID.class, new UUIDAccessor()); + + // Accessor for Geolocation classes + map.put(Point.class, new PointAccessor()); + } + + /** Making String Accessor easy to access. */ + public static final PropertyAccessor STRING = new StringAccessor(); + + /** + * Instantiates a new property accessor factory. + */ + private PropertyAccessorFactory() + { + } + + /** + * Gets the property accessor. + * + * @param clazz + * the clazz + * + * @return the property accessor + */ + @SuppressWarnings("unchecked") + public static PropertyAccessor getPropertyAccessor(Class clazz) + { + PropertyAccessor accessor; + if (clazz.isEnum()) + { + accessor = new EnumAccessor(); + } + else + { + accessor = map.get(clazz); + } + + // allow fall-back to Object streamer. + if (null == accessor) + { + if (clazz.getName().indexOf("$") > 0) + { + accessor = map.get(Enum.class); + } + else + { + accessor = map.get(Object.class); + } + + } + return accessor; + } + + /** + * Gets the property accessor. + * + * @param property + * the property + * + * @return the property accessor + */ + public static PropertyAccessor getPropertyAccessor(Field property) + { + return getPropertyAccessor(property.getType()); + } + + /** + * Adds the. + * + * @param key + * the key + * @param value + * the value + */ + public static void add(Class key, PropertyAccessor value) + { + map.put(key, value); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorHelper.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorHelper.java new file mode 100644 index 000000000..ff8198df3 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/PropertyAccessorHelper.java @@ -0,0 +1,552 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * Helper class to access fields. + * + * @author animesh.kumar + */ +public class PropertyAccessorHelper +{ + + /** + * Sets a byte-array onto a field. + * + * @param target + * the target + * @param field + * the field + * @param bytes + * the bytes + * + * @throws PropertyAccessException + * the property access exception + */ + public static void set(Object target, Field field, byte[] bytes) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(field); + Object value = accessor.fromBytes(field.getType(), bytes); + set(target, field, value); + } + + /** + * Sets a byte-array onto a field. + * + * @param target + * the target + * @param field + * the field + * @param fieldVal + * the field value + * + * @throws PropertyAccessException + * the property access exception + */ + public static void set(Object target, Field field, String fieldVal) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(field); + Object value = accessor.fromString(target.getClass(), fieldVal); + set(target, field, value); + } + + /** + * Sets an object onto a field. + * + * @param target + * the target + * @param field + * the field + * @param value + * the value + * + * @throws PropertyAccessException + * the property access exception + */ + public static void set(Object target, Field field, Object value) + { + + if (!field.isAccessible()) + { + field.setAccessible(true); + } + try + { + field.set(target, value); + } + catch (IllegalArgumentException iarg) + { + throw new PropertyAccessException(iarg); + } + catch (IllegalAccessException iacc) + { + throw new PropertyAccessException(iacc); + } + } + + /** + * Gets object from field. + * + * @param from + * the from + * @param field + * the field + * + * @return the object + * + * @throws PropertyAccessException + * the property access exception + */ + public static Object getObject(Object from, Field field) + { + + if (!field.isAccessible()) + { + field.setAccessible(true); + } + + try + { + return field.get(from); + } + catch (IllegalArgumentException iarg) + { + throw new PropertyAccessException(iarg); + } + catch (IllegalAccessException iacc) + { + throw new PropertyAccessException(iacc); + } + } + + /** + * Retutrns copy of object + * + * @param from + * @param field + * @return + */ + public static Object getObjectCopy(Object from, Field field) + { + + if (!field.isAccessible()) + { + field.setAccessible(true); + } + + try + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(field); + return accessor.getCopy(field.get(from)); + } + catch (IllegalArgumentException iarg) + { + throw new PropertyAccessException(iarg); + } + catch (IllegalAccessException iacc) + { + throw new PropertyAccessException(iacc); + } + } + + /** + * Gets the string. + * + * @param from + * the from + * @param field + * the field + * + * @return the string + * + * @throws PropertyAccessException + * the property access exception + */ + public static String getString(Object from, Field field) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(field); + Object object = getObject(from, field); + return object != null ? accessor.toString(object) : null; + + } + + /* + *//** + * Invokes corresponding accessor and returns string value for that + * object. + * + * @param obj + * object. + * + * @return string value for input object. + */ + /* + * public static String getString(Object obj) { PropertyAccessor accessor + * = PropertyAccessorFactory.getPropertyAccessor(obj.getClass()); return + * accessor.toString(obj); + * + * } + */ + /** + * Gets field value as byte-array. + * + * @param from + * the from + * @param field + * the field + * + * @return the byte[] + * + * @throws PropertyAccessException + * the property access exception + */ + public static byte[] get(Object from, Field field) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(field); + return accessor.toBytes(getObject(from, field)); + } + + /** + * Get identifier of an entity object by invoking getXXX() method. + * + * + * @param entity + * the entity + * @param metadata + * the metadata + * + * @return the id + * + * @throws PropertyAccessException + * the property access exception + */ + public static Object getId(Object entity, EntityMetadata metadata) + { + + // If an Entity has been wrapped in a Proxy, we can call the Proxy + // classes' getId() method + if (entity instanceof EnhanceEntity) + { + + return ((EnhanceEntity) entity).getEntityId(); + } + + // Otherwise, as Kundera currently supports only field access, access + // the underlying Entity's id field + + return getObject(entity, (Field) metadata.getIdAttribute().getJavaMember()); + } + + /** + * Sets Primary Key (Row key) into entity field that was annotated with @Id. + * + * @param entity + * the entity + * @param metadata + * the metadata + * @param rowKey + * the row key + * @throws PropertyAccessException + * the property access exception + */ + public static void setId(Object entity, EntityMetadata metadata, Object rowKey) + { + try + { + Field idField = (Field) metadata.getIdAttribute().getJavaMember(); + set(entity, idField, rowKey); + } + catch (IllegalArgumentException iarg) + { + throw new PropertyAccessException(iarg); + } + } + + /** + * Sets Primary Key (Row key) into entity field that was annotated with @Id. + * + * @param entity + * the entity + * @param metadata + * the metadata + * @param rowKey + * the row key + * @throws PropertyAccessException + * the property access exception + */ + public static void setId(Object entity, EntityMetadata metadata, byte[] rowKey) + { + try + { + Field idField = (Field) metadata.getIdAttribute().getJavaMember(); + + // PropertyAccessor accessor = + // PropertyAccessorFactory.getPropertyAccessor(idField); + // Object obj = accessor.fromBytes(idField.getClass(), rowKey); + // + // metadata.getWriteIdentifierMethod().invoke(entity, obj); + // + set(entity, idField, rowKey); + } + catch (IllegalArgumentException iarg) + { + throw new PropertyAccessException(iarg); + } + } + + /** + * Gets the embedded object. + * + * @param obj + * the obj + * @param fieldName + * the field name + * @return the embedded object + * @throws PropertyAccessException + * the property access exception + */ + @SuppressWarnings("null") + // TODO: Too much code, improve this, possibly by breaking it + public static final Object getObject(Object obj, String fieldName) + { + Field embeddedField; + try + { + embeddedField = obj.getClass().getDeclaredField(fieldName); + if (embeddedField != null) + { + if (!embeddedField.isAccessible()) + { + embeddedField.setAccessible(true); + } + Object embededObject = embeddedField.get(obj); + if (embededObject == null) + { + Class embeddedObjectClass = embeddedField.getType(); + if (Collection.class.isAssignableFrom(embeddedObjectClass)) + { + if (embeddedObjectClass.equals(List.class)) + { + return new ArrayList(); + } + else if (embeddedObjectClass.equals(Set.class)) + { + return new HashSet(); + } + } + else + { + embededObject = embeddedField.getType().newInstance(); + embeddedField.set(obj, embededObject); + } + + } + return embededObject; + } + else + { + throw new PropertyAccessException("Embedded object not found: " + fieldName); + } + + } + catch (Exception e) + { + throw new PropertyAccessException(e); + } + } + + /** + * Retrieves Generic class from a collection field that has only one + * argument. + * + * @param collectionField + * the collection field + * @return the generic class + */ + public static Class getGenericClass(Field collectionField) + { + Class genericClass = null; + if (collectionField == null) + { + return genericClass; + } + if (isCollection(collectionField.getType())) + { + Type[] parameters = ReflectUtils.getTypeArguments(collectionField); + if (parameters != null) + { + if (parameters.length == 1) + { + genericClass = (Class) parameters[0]; + } + else + { + throw new PropertyAccessException( + "Can't determine generic class from a field that has more than one parameters."); + } + } + } + return genericClass != null ? genericClass : collectionField.getType(); + } + + /** + * Retrieves Generic class from a collection field that has only one + * argument. + * + * @param collectionField + * the collection field + * @return the generic class + */ + public static List> getGenericClasses(Field collectionField) + { + List> genericClasses = new ArrayList>(); + if (collectionField == null) + { + return genericClasses; + } + Type[] parameters = ReflectUtils.getTypeArguments(collectionField); + if (parameters != null) + { + + for (Type parameter : parameters) + { + genericClasses.add((Class) parameter); + } + + } + + return genericClasses; + } + + /** + * Gets the declared fields. + * + * @param relationalField + * the relational field + * @return the declared fields + */ + public static Field[] getDeclaredFields(Field relationalField) + { + Field[] fields; + if (isCollection(relationalField.getType())) + { + fields = PropertyAccessorHelper.getGenericClass(relationalField).getDeclaredFields(); + } + else + { + fields = relationalField.getType().getDeclaredFields(); + } + return fields; + } + + /** + * Checks if is collection. + * + * @param clazz + * the clazz + * @return true, if is collection + */ + public static final boolean isCollection(Class clazz) + { + return Collection.class.isAssignableFrom(clazz); + + } + + public static final Object getObject(Class clazz) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(clazz); + return accessor.getInstance(clazz); + } + + public static final byte[] toBytes(Object o, Field f) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(f); + return accessor.toBytes(o); + } + + public static final byte[] toBytes(Object o, Class c) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(c); + return accessor.toBytes(o); + } + + public static Object fromSourceToTargetClass(Class targetClass, Class sourceClass, Object o) + { + if (!targetClass.equals(sourceClass)) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(sourceClass); + String s = accessor.toString(o); + accessor = PropertyAccessorFactory.getPropertyAccessor(targetClass); + return accessor.fromString(targetClass, s); + } + return o; + } + + public static Object fromDate(Class targetClass, Class sourceClass, Object o) + { + if (!targetClass.equals(sourceClass)) + { + PropertyAccessor accessor = PropertyAccessorFactory.getPropertyAccessor(sourceClass); + byte[] b = accessor.toBytes(o); + accessor = PropertyAccessorFactory.getPropertyAccessor(targetClass); + return accessor.fromBytes(targetClass, b); + } + return o; + } + + public static byte[] getBytes(Object o) + { + return PropertyAccessorFactory.getPropertyAccessor(o.getClass()).toBytes(o); + } + + public static String getString(Object o) + { + return o != null ? PropertyAccessorFactory.getPropertyAccessor(o.getClass()).toString(o) : null; + } + + public static Object getObject(Class clazz, byte[] b) + { + return PropertyAccessorFactory.getPropertyAccessor(clazz).fromBytes(clazz, b); + } + + public static final Collection getCollectionInstance(Field collectionField) + { + if (collectionField != null) + { + if (collectionField.getType().isAssignableFrom(List.class)) + { + return new ArrayList(); + } + else if (collectionField.getType().isAssignableFrom(Set.class)) + { + return new HashSet(); + } + } + return null; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigDecimalAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigDecimalAccessor.java new file mode 100644 index 000000000..55a5f2084 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigDecimalAccessor.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.io.UnsupportedEncodingException; +import java.math.BigDecimal; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class BigDecimalAccessor. + * + * @author amresh.singh + */ +public class BigDecimalAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public BigDecimal fromBytes(Class targetClass, byte[] b) + { + String s; + try + { + if (b == null) + { + return null; + } + s = new String(b, Constants.ENCODING); + } + catch (UnsupportedEncodingException e) + { + throw new PropertyAccessException(e); + } + return fromString(targetClass, s); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + BigDecimal b = (BigDecimal) object; + return b.toString().getBytes(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + if (object == null) + { + return null; + } + return object.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public BigDecimal fromString(Class targetClass, String s) + { + + return s != null ? new BigDecimal(s) : null; + } + + @Override + public BigDecimal getCopy(Object object) + { + BigDecimal b = (BigDecimal) object; + return object != null ? b : null; + } + + public BigDecimal getInstance(Class clazz) + { + return BigDecimal.TEN; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigIntegerAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigIntegerAccessor.java new file mode 100644 index 000000000..3290a71d8 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BigIntegerAccessor.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.math.BigInteger; + +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class BigIntegerAccessor. + * + * @author amresh.singh + */ +public class BigIntegerAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public BigInteger fromBytes(Class targetClass, byte[] b) + { + return b != null ? new BigInteger(b) : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + BigInteger b = (BigInteger) object; + return b.toByteArray(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + if (object == null) + { + return null; + } + return object.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public BigInteger fromString(Class targetClass, String s) + { + return s != null ? new BigInteger(s) : null; + } + + @Override + public BigInteger getCopy(Object object) + { + BigInteger i = (BigInteger) object; + return object != null ? new BigInteger(i.toByteArray()) : null; + } + + public BigInteger getInstance(Class clazz) + { + return BigInteger.TEN; + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BooleanAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BooleanAccessor.java new file mode 100644 index 000000000..b572ea572 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/BooleanAccessor.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class BooleanAccessor. + * + * @author Amresh Singh + */ +public class BooleanAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Boolean fromBytes(Class targetClass, byte[] data) + { + return (data == null || data.length == 0) ? false : data[0] != 0x00; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object != null) + { + + Boolean b = (Boolean) object; + + return new byte[] { (byte) (b ? 0x01 : 0x00) }; // bool -> {1 byte} + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Boolean fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + + Boolean b = new Boolean(s); + return b; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Boolean getCopy(Object object) + { + return object != null ? new Boolean((Boolean) object) : null; + } + + public Boolean getInstance(Class clazz) + { + return Boolean.TRUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ByteAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ByteAccessor.java new file mode 100644 index 000000000..140adee3e --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ByteAccessor.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.nio.ByteBuffer; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class ByteAccessor. + * + * @author Amresh Singh + */ +public class ByteAccessor implements PropertyAccessor +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(ByteAccessor.class); + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Byte fromBytes(Class targetClass, byte[] b) + { + try + { + if (b == null) + { + return null; + } + // return new Byte(new String(b, Constants.ENCODING)); + return (ByteBuffer.wrap(b).get()); + } + catch (NumberFormatException e) + { + log.warn("number format exception caught!,returning null!"); + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + Byte b = (Byte) object; + ByteBuffer buffer = ByteBuffer.allocate(8); + buffer.put(b); + return buffer.array(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Byte fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Byte b = new Byte(s); + return b; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Byte getCopy(Object object) + { + return object != null ? new Byte((Byte) object) : null; + } + + public Byte getInstance(Class clazz) + { + return Byte.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CalendarAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CalendarAccessor.java new file mode 100644 index 000000000..b7a11b7e6 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CalendarAccessor.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; + +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class CalendarAccessor. + * + * @author amresh.singh + */ +public class CalendarAccessor implements PropertyAccessor +{ + + /** The Constant DATE_FORMATTER. */ + private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss", Locale.ENGLISH); + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Calendar fromBytes(Class targetClass, byte[] b) + { + Calendar cal = Calendar.getInstance(); + Date d = new Date(); + if (b == null) + { + return null; + } + LongAccessor longAccessor = new LongAccessor(); + d.setTime(longAccessor.fromBytes(targetClass, b)); + cal.setTime(d); + return cal; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + Calendar cal = (Calendar) object; + // return + // DateAccessor.getFormattedObect(cal.getTime().toString()).getBytes(); + LongAccessor longAccessor = new LongAccessor(); + return longAccessor.toBytes(cal.getTime().getTime()); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + Calendar calendar = (Calendar) object; + + if (calendar == null) + { + return null; + } + return String.valueOf(calendar.getTime().getTime()); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Calendar fromString(Class targetClass, String s) + { + if (s == null) + { + return null; + } + Calendar cal = Calendar.getInstance(); + Date d; + // d = (Date)DATE_FORMATTER.parse(s); + d = DateAccessor.getDateByPattern(s); + cal.setTime(d); + return cal; + } + + @Override + public Calendar getCopy(Object object) + { + if (object == null) + return null; + Calendar c = (Calendar) object; + Calendar copy = Calendar.getInstance(); + copy.setTimeInMillis(c.getTimeInMillis()); + return copy; + } + + public Calendar getInstance(Class clazz) + { + return Calendar.getInstance(); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CharAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CharAccessor.java new file mode 100644 index 000000000..69f1929cd --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/CharAccessor.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class CharAccessor. + * + * @author Amresh Singh + */ +public class CharAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Character fromBytes(Class targetClass, byte[] data) + { + if (data == null || data.length != 2) + return 0x0; + + return (char) ((0xff & data[0]) << 8 | (0xff & data[1]) << 0); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + Character data = null; + if (object.getClass().isAssignableFrom(String.class)) + { + data = ((String) object).charAt(0); + } + else + { + data = (Character) object; + } + + return new byte[] { (byte) ((data >> 8) & 0xff), (byte) ((data >> 0) & 0xff), }; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + if(object == null) + { + return null; + } + + return object.toString(); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Character fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + throw new PropertyAccessException("Can't convert String " + s + " to character"); + } + + Character c = null; + if (s.length() == 1) + { + c = s.charAt(0); + } + else + { + c = Character.MIN_VALUE; + } + + return c; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Character getCopy(Object object) + { + return object != null ? new Character((Character) object) : null; + } + + public Character getInstance(Class clazz) + { + return Character.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DateAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DateAccessor.java new file mode 100644 index 000000000..2959db0bd --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DateAccessor.java @@ -0,0 +1,260 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.apache.commons.lang.StringUtils; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class DateAccessor. + * + * @author animesh.kumar + */ +public class DateAccessor implements PropertyAccessor +{ + + /** The Constant DATE_FORMATTER. */ + private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd MMM yyyy HH:mm:ss:S Z", + Locale.ENGLISH); + + /** The patterns. */ + private static List patterns = new ArrayList(15); + + static + { + patterns.add("E MMM dd HH:mm:ss z yyyy"); + patterns.add("dd MMM yyyy HH:mm:ss:SSS"); + patterns.add("dd MMM yyyy H:mm:ss:SSS"); + patterns.add("MM-dd-yyyy HH:mm:ss:SSS"); + patterns.add("MM/dd/yyyy HH:mm:ss:SSS"); + patterns.add("dd/MM/yyyy HH:mm:ss:SSS"); + patterns.add("dd-MM-yyyy HH:mm:ss:SSS"); + patterns.add("MMM/dd/yyyy HH:mm:ss:SSS"); + patterns.add("MMM-dd-yyyy HH:mm:ss:SSS"); + patterns.add("dd-MMM-yyyy HH:mm:ss:SSS"); + patterns.add("MM-dd-yyyy H:mm:ss:SSS"); + patterns.add("MM/dd/yyyy H:mm:ss:SSS"); + patterns.add("dd/MM/yyyy H:mm:ss:SSS"); + patterns.add("dd-MM-yyyy H:mm:ss:SSS"); + patterns.add("MMM/dd/yyyy H:mm:ss:SSS"); + patterns.add("MMM-dd-yyyy H:mm:ss:SSS"); + patterns.add("dd-MMM-yyyy H:mm:ss:SSS"); + patterns.add("MM-dd-yyyy HH:mm:ss"); + patterns.add("MM/dd/yyyy HH:mm:ss"); + patterns.add("dd/MM/yyyy HH:mm:ss"); + patterns.add("dd-MM-yyyy HH:mm:ss"); + patterns.add("MMM/dd/yyyy HH:mm:ss"); + patterns.add("MMM-dd-yyyy HH:mm:ss"); + patterns.add("dd-MMM-yyyy HH:mm:ss"); + patterns.add("MM-dd-yyyy H:mm:ss"); + patterns.add("MM/dd/yyyy H:mm:ss"); + patterns.add("dd/MM/yyyy H:mm:ss"); + patterns.add("dd-MM-yyyy H:mm:ss"); + patterns.add("MMM/dd/yyyy H:mm:ss"); + patterns.add("MMM-dd-yyyy H:mm:ss"); + patterns.add("dd-MMM-yyyy H:mm:ss"); + + patterns.add("MM-dd-yyyy"); + patterns.add("MM/dd/yyyy"); + patterns.add("dd/MM/yyyy"); + patterns.add("dd-MM-yyyy"); + patterns.add("MMM/dd/yyyy"); + patterns.add("MMM-dd-yyyy"); + patterns.add("dd-MMM-yyyy"); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public/* final */Date fromBytes(Class targetClass, byte[] bytes) + { + try + { + if (bytes == null) + { + return null; + } + + try + { + // In case date.getTime() is stored in DB. + LongAccessor longAccessor = new LongAccessor(); + + return new Date(longAccessor.fromBytes(targetClass, bytes)); + } + catch (NumberFormatException nfex) + { + return getDateByPattern(new String(bytes, Constants.ENCODING)); + + } + } + catch (Exception e) + { + throw new PropertyAccessException(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public/* final */byte[] toBytes(Object date) + { + try + { + if (date == null) + { + return null; + } + LongAccessor longAccessor = new LongAccessor(); + return longAccessor.toBytes(((Date) date).getTime()); + // return DATE_FORMATTER.format(((Date) + // date)).getBytes(Constants.ENCODING); + } + catch (Exception e) + { + throw new PropertyAccessException(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public/* final */String toString(Object object) + { + Date date = (Date) object; + + if (date == null) + { + return null; + } + + return String.valueOf(date.getTime()); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Date fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Date d = getDateByPattern(s); + return d; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + /** + * Get Date from given below formats. + * + * @param date + * Date pattern + * @return date instance + * @throws PropertyAccessException + * throws only if invalid format is supplied. + */ + public static Date getDateByPattern(String date) + { + if (StringUtils.isNumeric(date)) + { + return new Date(Long.parseLong(date)); + } + + for (String p : patterns) + { + try + { + DateFormat formatter = new SimpleDateFormat(p); + Date dt = formatter.parse(date); + return dt; + } + catch (IllegalArgumentException iae) + { + // Do nothing. + // move to next pattern. + } + catch (ParseException e) + { + // Do nothing. + // move to next pattern. + } + + } + + throw new PropertyAccessException("Required Date format is not supported!" + date); + } + + @Override + public Date getCopy(Object object) + { + Date d = (Date) object; + return d != null ? new Date(d.getTime()) : null; + } + + /** + * Just to verify with supported types of date pattern. Get Date from given + * below formats + * + * @param date + * Date pattern + * @return date instance + * @throws PropertyAccessException + * throws only if invalid format is supplied. + */ + public static String getFormattedObect(String date) + { + return date != null ? getDateByPattern(date).toString() : null; + } + + public Date getInstance(Class clazz) + { + return new Date(); + } +} \ No newline at end of file diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DoubleAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DoubleAccessor.java new file mode 100644 index 000000000..6b4f286d7 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/DoubleAccessor.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class DoubleAccessor. + * + * @author Amresh Singh + */ +public class DoubleAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Double fromBytes(Class targetClass, byte[] data) + { + if (data == null || data.length != 8) + return (double) 0x0; + + return Double.longBitsToDouble(toLong(data)); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) throws PropertyAccessException + { + return object != null ? fromLong(Double.doubleToRawLongBits((Double) object)) : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /** + * To long. + * + * @param data + * the data + * @return the long + */ + private long toLong(byte[] data) + { + if (data == null || data.length != 8) + return 0x0; + // ---------- + return (long) ( + // (Below) convert to longs before shift because digits + // are lost with ints beyond the 32-bit limit + (long) (0xff & data[0]) << 56 | (long) (0xff & data[1]) << 48 | (long) (0xff & data[2]) << 40 + | (long) (0xff & data[3]) << 32 | (long) (0xff & data[4]) << 24 | (long) (0xff & data[5]) << 16 + | (long) (0xff & data[6]) << 8 | (long) (0xff & data[7]) << 0); + } + + /** + * From long. + * + * @param data + * the data + * @return the byte[] + */ + private byte[] fromLong(long data) + { + return new byte[] { (byte) ((data >> 56) & 0xff), (byte) ((data >> 48) & 0xff), (byte) ((data >> 40) & 0xff), + (byte) ((data >> 32) & 0xff), (byte) ((data >> 24) & 0xff), (byte) ((data >> 16) & 0xff), + (byte) ((data >> 8) & 0xff), (byte) ((data >> 0) & 0xff), }; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Double fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Double d = new Double(s); + return d; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Double getCopy(Object object) + { + return object != null ? new Double((Double) object) : null; + } + + public Double getInstance(Class clazz) + { + return Double.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/EnumAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/EnumAccessor.java new file mode 100644 index 000000000..d51325597 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/EnumAccessor.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.io.UnsupportedEncodingException; + +import com.impetus.kundera.Constants; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * @author amresh.singh + * + */ +@SuppressWarnings("rawtypes") +public class EnumAccessor implements PropertyAccessor +{ + + @Override + public Enum fromBytes(Class targetClass, byte[] b) + { + String s = null; + try + { + if (b == null) + { + return null; + } + s = new String(b, Constants.ENCODING); + } + catch (UnsupportedEncodingException e) + { + throw new PropertyAccessException(e); + } + return fromString(targetClass, s); + } + + @Override + public byte[] toBytes(Object object) + { + if (object == null) + { + return null; + } + String s = toString(object); + try + { + return s.getBytes(Constants.ENCODING); + } + catch (UnsupportedEncodingException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public String toString(Object object) + { + if (object == null) + { + return null; + } + Enum en = (Enum) object; + return en.name(); + } + + @Override + public Enum fromString(Class targetClass, String string) + { + if (targetClass != null && string != null) + { + try + { + return Enum.valueOf(targetClass, string.trim().toUpperCase()); + } + catch (IllegalArgumentException ex) + { + throw new PropertyAccessException(ex); + } + } + + return null; + } + + @Override + public Enum getCopy(Object object) + { + if (object != null) + { + return fromString(object.getClass(), toString(object)); + } + return null; + } + + public Enum getInstance(Class clazz) + { + return null; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/FloatAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/FloatAccessor.java new file mode 100644 index 000000000..3593e37d1 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/FloatAccessor.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class FloatAccessor. + * + * @author Amresh Singh + */ +public class FloatAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Float fromBytes(Class targetClass, byte[] data) + { + if (data == null || data.length != 4) + return (float) 0x0; + + return Float.intBitsToFloat(toInt(data)); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + return object != null ? fromInt(Float.floatToRawIntBits((Float) object)) : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /** + * From int. + * + * @param data + * the data + * @return the byte[] + */ + private byte[] fromInt(int data) + { + return new byte[] { (byte) ((data >> 24) & 0xff), (byte) ((data >> 16) & 0xff), (byte) ((data >> 8) & 0xff), + (byte) ((data >> 0) & 0xff), }; + } + + /** + * To int. + * + * @param data + * the data + * @return the int + */ + private int toInt(byte[] data) + { + if (data == null || data.length != 4) + return 0x0; + + return (int) ( // NOTE: type cast not necessary for int + (0xff & data[0]) << 24 | (0xff & data[1]) << 16 | (0xff & data[2]) << 8 | (0xff & data[3]) << 0); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Float fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Float f = new Float(s); + return f; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Float getCopy(Object object) + { + return object != null ? (Float) object : null; + } + + public Float getInstance(Class clazz) + { + return Float.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/IntegerAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/IntegerAccessor.java new file mode 100644 index 000000000..d42557ae9 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/IntegerAccessor.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class IntegerAccessor. + * + * @author animesh.kumar + */ +public class IntegerAccessor implements PropertyAccessor +{ + + /* @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) */ + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public final Integer fromBytes(Class targetClass, byte[] b) + { + if (b == null) + { + return null; + } + return ((b[0] << 24) + ((b[1] & 0xFF) << 16) + ((b[2] & 0xFF) << 8) + (b[3] & 0xFF)); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public final byte[] toBytes(Object val) + { + if (val != null) + { + Integer value = (Integer) (val); + return new byte[] { (byte) (value >>> 24), (byte) (value >>> 16), (byte) (value >>> 8), + (byte) value.intValue() }; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Integer fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Integer i = new Integer(s); + return i; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Integer getCopy(Object object) + { + return object != null ? (Integer) object : null; + } + + public Integer getInstance(Class clazz) + { + return Integer.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/LongAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/LongAccessor.java new file mode 100644 index 000000000..d34e8d921 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/LongAccessor.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.nio.ByteBuffer; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class LongAccessor. + * + * @author animesh.kumar + */ +public class LongAccessor implements PropertyAccessor +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public final Long fromBytes(Class targetClass, byte[] bytes) + { + if (bytes == null || bytes.length != 8) + { + return null; + } + return (ByteBuffer.wrap(bytes).getLong()); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public final byte[] toBytes(Object object) + { + if (object != null) + { + Long l = (Long) object; + ByteBuffer buffer = ByteBuffer.allocate(8); + buffer.putLong(l); + return buffer.array(); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public final String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Long fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Long l = new Long(s); + return l; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Long getCopy(Object object) + { + return object != null ? (Long) object : null; + } + + public Long getInstance(Class clazz) + { + return Long.MAX_VALUE; + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ObjectAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ObjectAccessor.java new file mode 100644 index 000000000..b0cda72f0 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/ObjectAccessor.java @@ -0,0 +1,232 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class ObjectAccessor. + * + * @author animesh.kumar + */ +public class ObjectAccessor implements PropertyAccessor +{ + + public static Logger log = LoggerFactory.getLogger(ObjectAccessor.class); + + /* @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) */ + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public final Object fromBytes(Class targetClass, byte[] bytes) + { + try + { + if (bytes == null) + { + return null; + } + if (targetClass != null && targetClass.equals(byte[].class)) + { + return bytes; + } + ObjectInputStream ois; + ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); + Object o = ois.readObject(); + ois.close(); + return o; + } + catch (IOException e) + { + throw new PropertyAccessException(e); + } + catch (ClassNotFoundException e) + { + throw new PropertyAccessException(e); + } + + } + + /* + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public final byte[] toBytes(Object o) + { + + try + { + if (o != null) + { + if (o instanceof byte[]) + { + return (byte[]) o; + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(o); + oos.close(); + return baos.toByteArray(); + } + } + catch (IOException e) + { + throw new PropertyAccessException(e); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public final String toString(Object object) + { + return object != null ? object.toString() : null; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Object fromString(Class targetClass, String s) + { + try + { + if (s == null) + { + return null; + } + Object o = (Object) s; + return o; + } + catch (NumberFormatException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Object getCopy(Object object) + { + if (object == null) + return null; + + if (object instanceof byte[]) + { + byte[] byteArr = (byte[]) object; + return byteArr.clone(); + } + else if (object instanceof Cloneable) + { + Class clazz = object.getClass(); + + Object o = null; + try + { + Method m = clazz.getMethod("clone"); + o = m.invoke(clazz); + } + catch (SecurityException e) + { + log.warn("Object of class " + object.getClass() + " can't be cloned, due to exception:" + + e.getMessage()); + return object; + } + catch (IllegalArgumentException e) + { + log.warn("Object of class " + object.getClass() + " can't be cloned, due to exception:" + + e.getMessage()); + return object; + } + catch (NoSuchMethodException e) + { + log.warn("Object of class " + object.getClass() + " can't be cloned, due to exception:" + + e.getMessage()); + return object; + } + catch (IllegalAccessException e) + { + log.warn("Object of class " + object.getClass() + " can't be cloned, due to exception:" + + e.getMessage()); + return object; + } + catch (InvocationTargetException e) + { + log.warn("Object of class " + object.getClass() + " can't be cloned, due to exception:" + + e.getMessage()); + return object; + } + return o; + } + else + { + return object; + } + } + + public Object getInstance(Class clazz) + { + Object o = null; + try + { + o = clazz.newInstance(); + return o; + } + catch (InstantiationException ie) + { + log.warn("Instantiation exception,caused by :" + ie.getMessage()); + return null; + } + catch (IllegalAccessException iae) + { + log.warn("Illegal access exception,caused by :" + iae.getMessage()); + return null; + } + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/PointAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/PointAccessor.java new file mode 100644 index 000000000..ee4994572 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/PointAccessor.java @@ -0,0 +1,117 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.kundera.property.accessor; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +/** + * Property Accessor for {@link Point} + * + * @author amresh.singh + */ +public class PointAccessor implements PropertyAccessor +{ + + @Override + public Point fromBytes(Class targetClass, byte[] b) + { + ObjectInputStream ois; + Point o; + try + { + ois = new ObjectInputStream(new ByteArrayInputStream(b)); + o = (Point) ois.readObject(); + ois.close(); + } + catch (IOException e) + { + throw new PropertyAccessException(e); + } + catch (ClassNotFoundException e) + { + throw new PropertyAccessException(e); + } + return o; + } + + @Override + public byte[] toBytes(Object object) + { + ByteArrayOutputStream baos; + try + { + baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(object); + oos.close(); + return baos.toByteArray(); + } + catch (IOException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public String toString(Object object) + { + return object != null ? object.toString() : null; + } + + @Override + public Point fromString(Class targetClass, String s) + { + if (s == null) + return null; + + WKTReader reader = new WKTReader(); + try + { + return new Point((com.vividsolutions.jts.geom.Point) reader.read(s)); + } + catch (ParseException e) + { + throw new PropertyAccessException(e); + } + } + + @Override + public Point getCopy(Object object) + { + if (object == null) + return null; + + Point p = (Point) object; + return new Point(p.getX(), p.getY()); + } + + @Override + public Object getInstance(Class clazz) + { + return new Point(0.0, 0.0); + } + +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLDateAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLDateAccessor.java new file mode 100644 index 000000000..a3a8b3262 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLDateAccessor.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.sql.Date; + +import org.apache.commons.lang.StringUtils; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class SQLDateAccessor. + * + * @author amresh.singh + */ +public class SQLDateAccessor implements PropertyAccessor + +{ + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.property.PropertyAccessor#fromBytes(byte[]) + */ + @Override + public Date fromBytes(Class targetClass, byte[] b) + { + try + { + if (b == null) + { + return null; + } + + // In case date.getTime() is stored in DB. + LongAccessor longAccessor = new LongAccessor(); + + return new Date(longAccessor.fromBytes(targetClass, b)); + } + catch (Exception e) + { + throw new PropertyAccessException(e); + } + + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toBytes(java.lang.Object) + */ + @Override + public byte[] toBytes(Object object) + { + + try + { + if (object == null) + { + return null; + } + LongAccessor longAccessor = new LongAccessor(); + return longAccessor.toBytes(((Date) object).getTime()); + // return DATE_FORMATTER.format(((Date) + // date)).getBytes(Constants.ENCODING); + } + catch (Exception e) + { + throw new PropertyAccessException(e); + } + + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#toString(java.lang.Object) + */ + @Override + public String toString(Object object) + { + Date date = (Date) object; + + if (date == null) + { + return null; + } + + return String.valueOf(date.getTime()); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.property.PropertyAccessor#fromString(java.lang.String + * ) + */ + @Override + public Date fromString(Class targetClass, String s) + { + + if (s == null) + { + return null; + } + if (StringUtils.isNumeric(s)) + { + return new Date(Long.parseLong(s)); + } + Date d = Date.valueOf(s); + return d; + } + + @Override + public Date getCopy(Object object) + { + Date d = (Date) object; + return d != null ? new Date(d.getTime()) : null; + } + + public Date getInstance(Class clazz) + { + return new Date(Integer.MAX_VALUE); + } +} diff --git a/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLTimeAccessor.java b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLTimeAccessor.java new file mode 100644 index 000000000..67b049327 --- /dev/null +++ b/src/kundera-core/src/main/java/com/impetus/kundera/property/accessor/SQLTimeAccessor.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.kundera.property.accessor; + +import java.sql.Time; + +import org.apache.commons.lang.StringUtils; + +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessor; + +/** + * The Class SQLTimeAccessor. + * + * @author amresh.singh + */ +public class SQLTimeAccessor implements PropertyAccessor
+ CASSANDRAUSERXYZ + + + + + + + + + +
+ + CASSANDRASUPERUSER + + + + + + + +
+ + + + KunderaCounterColumn + + + counters + + + + +
+ + SuperCounters + + + + +
+ + InvalidCounterColumnEntity + + + + +
+ + ValidCounterColumnFamily + + + + +
+
+
+ + KunderaExamples + + + + + + + + + + + hbase + + + + + + + + + HBASEUSERXYZ + + + HBASEUSERXYZ + + + + + + + +
+
+
+ + KunderaExamples + + + AGE + + + + + + + +
+ + PERSON_NAME + + + + + + + +
+
+
+
+
+ + \ No newline at end of file diff --git a/src/kundera-core/src/test/resources/kunderaTestDataType.xml b/src/kundera-core/src/test/resources/kunderaTestDataType.xml new file mode 100644 index 000000000..6c07fe3c0 --- /dev/null +++ b/src/kundera-core/src/test/resources/kunderaTestDataType.xml @@ -0,0 +1,42 @@ + + + + + cassandra + + + CompositeCassandra + + + + + + + + DC1 + 3 + + + DC2 + 2 + + + + + CompositeUserDataType + + + + + + + + + +
+
+
+
+
+
+
\ No newline at end of file diff --git a/src/kundera-core/src/test/resources/log4j.properties b/src/kundera-core/src/test/resources/log4j.properties new file mode 100644 index 000000000..89ebcbeaf --- /dev/null +++ b/src/kundera-core/src/test/resources/log4j.properties @@ -0,0 +1,15 @@ +log4j.rootLogger=DEBUG,CONSOLE + +### direct log messages to stdout ### +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.File=${user.home}/kundera.log +# Rollover at midnight +log4j.appender.DRFA.DatePattern=.yyyy-MM-dd +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +# Pattern format: Date LogLevel LoggerName LogMessage +log4j.appender.DRFA.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n + + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n diff --git a/src/kundera-hbase/pom.xml b/src/kundera-hbase/pom.xml new file mode 100644 index 000000000..f3142be73 --- /dev/null +++ b/src/kundera-hbase/pom.xml @@ -0,0 +1,156 @@ + + 4.0.0 + + + com.impetus + kundera + 2.7-SNAPSHOT + + com.impetus.client + kundera-hbase + jar + kundera-hbase + http://maven.apache.org + + + 1.1.1 + 0.94.3 + + + + + + + + junit + junit + 4.8.2 + test + + + + com.impetus.core + kundera-core + ${project.version} + + + com.impetus.core + kundera-core + ${project.version} + test-jar + test + + + org.apache.hbase + hbase + ${hbase.version} + + + org.slf4j + slf4j-api + + + + + org.apache.hadoop + hadoop-core + ${hadoop.version} + + + + + + + org.apache.hadoop + hadoop-test + ${hadoop.version} + test + + + + org.apache.hbase + hbase + ${hbase.version} + test-jar + test + + + org.slf4j + slf4j-log4j12 + 1.6.3 + test + + + + org.slf4j + slf4j-api + 1.6.3 + + + + + + + + + + maven-assembly-plugin + 2.2.1 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + + + + diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClient.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClient.java new file mode 100644 index 000000000..53c43e545 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClient.java @@ -0,0 +1,832 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EntityType; + +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.HTablePool; +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; +import org.apache.hadoop.hbase.filter.KeyOnlyFilter; +import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.admin.DataHandler; +import com.impetus.client.hbase.admin.HBaseDataHandler; +import com.impetus.client.hbase.admin.HBaseDataHandler.HBaseDataWrapper; +import com.impetus.client.hbase.query.HBaseQuery; +import com.impetus.client.hbase.utils.HBaseUtils; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.generator.TableGenerator; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.TableGeneratorDiscriptor; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * HBase client. + * + * @author impetus + */ +public class HBaseClient extends ClientBase implements Client, Batcher, ClientPropertiesSetter, + TableGenerator +{ + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(HBaseClient.class); + + /** The handler. */ + private DataHandler handler; + + /** The reader. */ + private EntityReader reader; + + private List nodes = new ArrayList(); + + private int batchSize; + + private Map puProperties; + + /** + * Instantiates a new h base client. + * + * @param indexManager + * the index manager + * @param conf + * the conf + * @param hTablePool + * the h table pool + * @param reader + * the reader + * @param persistenceUnit + * the persistence unit + * @param puProperties + */ + public HBaseClient(IndexManager indexManager, HBaseConfiguration conf, HTablePool hTablePool, EntityReader reader, + String persistenceUnit, Map puProperties, ClientMetadata clientMetadata) + { + this.indexManager = indexManager; + this.handler = new HBaseDataHandler(conf, hTablePool); + this.reader = reader; + this.persistenceUnit = persistenceUnit; + this.puProperties = puProperties; + + this.clientMetadata = clientMetadata; + + getBatchSize(persistenceUnit, this.puProperties); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#find(java.lang.Class, + * java.lang.Object, java.util.List) + */ + @Override + public Object find(Class entityClass, Object rowId) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + List relationNames = entityMetadata.getRelationNames(); + // columnFamily has a different meaning for HBase, so it won't be used + // here + String tableName = entityMetadata.getTableName(); + Object enhancedEntity = null; + List results = null; + try + { + if (rowId == null) + { + return null; + } + results = handler.readData(tableName, entityMetadata.getEntityClazz(), entityMetadata, rowId, + relationNames, null); + if (results != null) + { + enhancedEntity = results.get(0); + } + } + catch (IOException e) + { + log.error("Error during find by id, Caused by: .", e); + throw new KunderaException(e); + } + return enhancedEntity; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#findAll(java.lang.Class, + * java.lang.Object[]) + */ + @Override + public List findAll(Class entityClass, String[] columnsToSelect, Object... rowIds) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + if (rowIds == null) + { + return null; + } + List results; + try + { + results = handler.readAll(entityMetadata.getTableName(), entityMetadata.getEntityClazz(), entityMetadata, + Arrays.asList(rowIds), entityMetadata.getRelationNames()); + } + catch (IOException ioex) + { + log.error("Error during find All , Caused by: .", ioex); + throw new KunderaException(ioex); + } + return results; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#find(java.lang.Class, + * java.util.Map) + */ + @Override + public List find(Class entityClass, Map col) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(getPersistenceUnit(), entityClass); + List entities = new ArrayList(); + Map columnFamilyNameToFieldMap = MetadataUtils.createSuperColumnsFieldMap(entityMetadata); + for (String columnFamilyName : col.keySet()) + { + String entityId = col.get(columnFamilyName); + if (entityId != null) + { + E e = null; + try + { + List results = handler.readData(entityMetadata.getTableName(), entityMetadata.getEntityClazz(), + entityMetadata, entityId, null, null); + if (results != null) + { + e = (E) results.get(0); + } + } + catch (IOException ioex) + { + log.error("Error during find for embedded entities, Caused by: .", ioex); + + throw new KunderaException(ioex); + } + + Field columnFamilyField = columnFamilyNameToFieldMap.get(columnFamilyName.substring(0, + columnFamilyName.indexOf("|"))); + Object columnFamilyValue = PropertyAccessorHelper.getObject(e, columnFamilyField); + if (Collection.class.isAssignableFrom(columnFamilyField.getType())) + { + entities.addAll((Collection) columnFamilyValue); + } + else + { + entities.add((E) columnFamilyValue); + } + } + } + return entities; + } + + /** + * Method to find entities using JPQL(converted into FilterList.) + * + * @param + * parameterized entity class. + * @param entityClass + * entity class. + * @param metadata + * entity metadata. + * @return list of entities. + */ + public List findByQuery(Class entityClass, EntityMetadata metadata, Filter f, String... columns) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + List relationNames = entityMetadata.getRelationNames(); + // columnFamily has a different meaning for HBase, so it won't be used + // here + String tableName = entityMetadata.getTableName(); + List results = null; + + FilterList filter = new FilterList(); + if (f != null) + { + filter.addFilter(f); + } + if (isFindKeyOnly(metadata, columns)) + { + columns = null; + filter.addFilter(new KeyOnlyFilter()); + } + + try + { + results = handler.readData(tableName, entityMetadata.getEntityClazz(), entityMetadata, null, relationNames, + filter, columns); + } + catch (IOException ioex) + { + log.error("Error during find by query, Caused by: .", ioex); + throw new KunderaException(ioex); + } + return results != null ? results : new ArrayList(); + } + + /** + * Handles find by range query for given start and end row key range values. + * + * @param + * parameterized entity class. + * @param entityClass + * entity class. + * @param metadata + * entity metadata + * @param startRow + * start row. + * @param endRow + * end row. + * @return collection holding results. + */ + public List findByRange(Class entityClass, EntityMetadata metadata, byte[] startRow, byte[] endRow, + String[] columns, Filter f) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + // columnFamily has a different meaning for HBase, so it won't be used + // here + String tableName = entityMetadata.getTableName(); + // Object enhancedEntity = null; + List results = new ArrayList(); + + FilterList filter = new FilterList(); + if (f != null) + { + filter.addFilter(f); + } + if (isFindKeyOnly(metadata, columns)) + { + columns = null; + filter.addFilter(new KeyOnlyFilter()); + } + + try + { + results = handler.readDataByRange(tableName, entityClass, metadata, startRow, endRow, columns, filter); + + } + catch (IOException ioex) + { + log.error("Error during find by range, Caused by: .", ioex); + throw new KunderaException(ioex); + } + return results; + } + + /** + * @param metadata + * @param columns + * @return + */ + private boolean isFindKeyOnly(EntityMetadata metadata, String[] columns) + { + int noOFColumnsToFind = 0; + boolean findIdOnly = false; + if (columns != null) + { + for (String column : columns) + { + if (column != null) + { + if (column.equals(((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName())) + { + noOFColumnsToFind++; + findIdOnly = true; + } + else + { + noOFColumnsToFind++; + findIdOnly = false; + } + } + } + } + if (noOFColumnsToFind == 1 && findIdOnly) + { + return true; + } + return false; + } + + /** + * Close handlers instance and reinstate pu properties. + * + */ + @Override + public void close() + { + handler.shutdown(); + puProperties = null; + } + + /** + * Setter for filter. + * + * @param filter + * filter. + */ + public void setFilter(Filter filter) + { + ((HBaseDataHandler) handler).setFilter(filter); + } + + public void addFilter(final String columnFamily, Filter filter) + { + ((HBaseDataHandler) handler).addFilter(columnFamily, filter); + } + + public void resetFilter() + { + ((HBaseDataHandler) handler).resetFilter(); + } + + /** + * Setter for filter. + * + * @param filter + * filter. + */ + public void setFetchSize(int fetchSize) + { + ((HBaseDataHandler) handler).setFetchSize(fetchSize); + } + + /** + * On persist. + * + * @param entityMetadata + * the entity metadata + * @param entity + * the entity + * @param id + * the id + * @param relations + * the relations + */ + @Override + protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id, List relations) + { + String tableName = entityMetadata.getTableName(); + + try + { + // Write data to HBase + handler.writeData(tableName, entityMetadata, entity, id, relations); + } + catch (IOException e) + { + throw new PersistenceException(e); + } + } + + @Override + public void persistJoinTable(JoinTableData joinTableData) + { + String joinTableName = joinTableData.getJoinTableName(); + String invJoinColumnName = joinTableData.getInverseJoinColumnName(); + Map> joinTableRecords = joinTableData.getJoinTableRecords(); + + for (Object key : joinTableRecords.keySet()) + { + Set values = joinTableRecords.get(key); + Object joinColumnValue = key; + + Map columns = new HashMap(); + for (Object childValue : values) + { + Object invJoinColumnValue = childValue; + columns.put(invJoinColumnName + "_" + invJoinColumnValue, invJoinColumnValue); + } + + if (columns != null && !columns.isEmpty()) + { + try + { + handler.createTableIfDoesNotExist(joinTableName, joinTableName); + handler.writeJoinTableData(joinTableName, joinColumnValue, columns); + } + catch (IOException e) + { + throw new PersistenceException(e); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.client.Client#getForeignKeysFromJoinTable(java.lang + * .String, java.lang.String, java.lang.String, + * com.impetus.kundera.metadata.model.EntityMetadata, + * com.impetus.kundera.persistence.handler.impl.EntitySaveGraph) + */ + @Override + public List getColumnsById(String schemaName, String joinTableName, String joinColumnName, + String inverseJoinColumnName, Object parentId, Class columnJavaType) + { + return handler.getForeignKeysFromJoinTable(joinTableName, parentId, inverseJoinColumnName); + + } + + public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) + { + try + { + handler.deleteRow(columnValue, tableName); + } + catch (IOException ioex) + { + log.error("Error during get columns by key. Caused by: .", ioex); + throw new PersistenceException(ioex); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#delete(java.lang.Object, + * java.lang.Object) + */ + @Override + public void delete(Object entity, Object pKey) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + deleteByColumn(metadata.getSchema(), metadata.getTableName(), + ((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName(), pKey); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#findByRelation(java.lang.String, + * java.lang.Object, java.lang.Class) + */ + @Override + public List findByRelation(String colName, Object colValue, Class entityClazz) + { + CompareOp operator = HBaseUtils.getOperator("=", false); + + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClazz); + + String columnFamilyName = m.getTableName(); + + byte[] valueInBytes = HBaseUtils.getBytes(colValue); + SingleColumnValueFilter f = null; + f = new SingleColumnValueFilter(Bytes.toBytes(columnFamilyName), Bytes.toBytes(colName), operator, valueInBytes); + + try + { + return ((HBaseDataHandler) handler) + .scanData(f, m.getTableName(), entityClazz, m, columnFamilyName, colName); + } + catch (IOException ioe) + { + log.error("Error during find By Relation, Caused by: .", ioe); + throw new KunderaException(ioe); + } + catch (InstantiationException ie) + { + log.error("Error during find By Relation, Caused by: .", ie); + throw new KunderaException(ie); + } + catch (IllegalAccessException iae) + { + log.error("Error during find By Relation, Caused by: .", iae); + throw new KunderaException(iae); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#getReader() + */ + @Override + public EntityReader getReader() + { + return reader; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#getQueryImplementor() + */ + @Override + public Class getQueryImplementor() + { + return HBaseQuery.class; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#findIdsByColumn(java.lang.String, + * java.lang.String, java.lang.String, java.lang.Object, java.lang.Class) + */ + @Override + public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName, + Object columnValue, Class entityClazz) + { + CompareOp operator = HBaseUtils.getOperator("=", false); + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClazz); + + byte[] valueInBytes = HBaseUtils.getBytes(columnValue); + Filter f = new SingleColumnValueFilter(Bytes.toBytes(tableName), Bytes.toBytes(columnName), operator, + valueInBytes); + KeyOnlyFilter keyFilter = new KeyOnlyFilter(); + FilterList filterList = new FilterList(f, keyFilter); + try + { + return handler.scanRowyKeys(filterList, tableName, tableName, columnName + "_" + columnValue, m + .getIdAttribute().getBindableJavaType()); + } + catch (IOException e) + { + log.error("Error while executing findIdsByColumn(), Caused by: .", e); + throw new KunderaException(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.api.Batcher#addBatch(com.impetus.kundera + * .graph.Node) + */ + public void addBatch(Node node) + { + if (node != null) + { + nodes.add(node); + } + onBatchLimit(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#getBatchSize() + */ + @Override + public int getBatchSize() + { + return batchSize; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#clear() + */ + @Override + public void clear() + { + if (nodes != null) + { + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#executeBatch() + */ + @Override + public int executeBatch() + { + Map> data = new HashMap>(); + + try + { + for (Node node : nodes) + { + if (node.isDirty()) + { + node.handlePreEvent(); + HTableInterface hTable = null; + Object rowKey = node.getEntityId(); + Object entity = node.getData(); + if (node.isInState(RemovedState.class)) + { + delete(entity, rowKey); + } + else + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(node.getDataClass()); + + HBaseDataWrapper columnWrapper = new HBaseDataHandler.HBaseDataWrapper(rowKey, + new java.util.HashSet(), entity, metadata.getTableName()); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata() + .getMetamodel(metadata.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(node.getDataClass()); + + List embeddableData = new ArrayList(); + + hTable = ((HBaseDataHandler) handler).gethTable(metadata.getTableName()); + ((HBaseDataHandler) handler).preparePersistentData(metadata.getTableName(), entity, rowKey, + metaModel, entityType.getAttributes(), columnWrapper, embeddableData); + + List dataSet = null; + if (data.containsKey(hTable)) + { + dataSet = data.get(metadata.getTableName()); + addRecords(columnWrapper, embeddableData, dataSet); + } + else + { + dataSet = new ArrayList(); + addRecords(columnWrapper, embeddableData, dataSet); + data.put(hTable, dataSet); + } + } + node.handlePostEvent(); + } + } + + if (!data.isEmpty()) + { + ((HBaseDataHandler) handler).batch_insert(data); + } + return data.size(); + } + catch (IOException ioex) + { + log.error("Error while executing batch insert/update, Caused by: .", ioex); + throw new KunderaException(ioex); + } + + } + + /** + * Add records to data wrapper. + * + * @param columnWrapper + * column wrapper + * @param embeddableData + * embeddable data + * @param dataSet + * data collection set + */ + private void addRecords(HBaseDataWrapper columnWrapper, List embeddableData, + List dataSet) + { + dataSet.add(columnWrapper); + + if (!embeddableData.isEmpty()) + { + dataSet.addAll(embeddableData); + } + } + + /** + * Check on batch limit. + */ + private void onBatchLimit() + { + if (batchSize > 0 && batchSize == nodes.size()) + { + executeBatch(); + nodes.clear(); + } + } + + /** + * @param persistenceUnit + * @param puProperties + */ + private void getBatchSize(String persistenceUnit, Map puProperties) + { + String batch_Size = puProperties != null ? (String) puProperties.get(PersistenceProperties.KUNDERA_BATCH_SIZE) + : null; + if (batch_Size != null) + { + batchSize = Integer.valueOf(batch_Size); + if (batchSize == 0) + { + throw new IllegalArgumentException("kundera.batch.size property must be numeric and > 0"); + } + } + else + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + batchSize = puMetadata.getBatchSize(); + } + } + + @Override + public void populateClientProperties(Client client, Map properties) + { + new HBaseClientProperties().populateClientProperties(client, properties); + } + + @Override + public Long generate(TableGeneratorDiscriptor discriptor) + { + try + { + HTableInterface hTable = ((HBaseDataHandler) handler).gethTable(discriptor.getTable()); + Long latestCount = hTable.incrementColumnValue(discriptor.getPkColumnValue().getBytes(), discriptor + .getTable().getBytes(), discriptor.getValueColumnName().getBytes(), 1); + if (latestCount == 1) + { + return (long) discriptor.getInitialValue(); + } + else + { + return (latestCount - 1) * discriptor.getAllocationSize(); + } + } + catch (IOException ioex) + { + log.error("Error while generating id for entity, Caused by: .", ioex); + throw new KunderaException(ioex); + } + } + + public void reset() + { + ((HBaseDataHandler) handler).reset(); + } + + public Object next(EntityMetadata m) + { + return ((HBaseDataHandler) handler).next(m); + } + + public boolean hasNext() + { + return ((HBaseDataHandler) handler).hasNext(); + } + + public HBaseDataHandler getHandle() + { + return ((HBaseDataHandler) handler).getHandle(); + } + +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientFactory.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientFactory.java new file mode 100644 index 000000000..2d86ef7f2 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientFactory.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.client.HTablePool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.config.HBasePropertyReader; +import com.impetus.client.hbase.schemamanager.HBaseSchemaManager; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.GenericClientFactory; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * HBaseClientFactory, instantiates client for HBase + */ +public class HBaseClientFactory extends GenericClientFactory +{ + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(HBaseClientFactory.class); + + /** The conf. */ + private HBaseConfiguration conf; + + /** The h table pool. */ + private HTablePool hTablePool; + + /** The Constant DEFAULT_POOL_SIZE. */ + private static final int DEFAULT_POOL_SIZE = 100; + + private static final String DEFAULT_ZOOKEEPER_PORT = "2181"; + + /** The pool size. */ + private int poolSize; + + @Override + public void initialize(Map externalProperty) + { + setExternalProperties(externalProperty); + initializePropertyReader(); + // Initialize HBase configuration + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(getPersistenceUnit()); + + String node = null; + String port = null; + String poolSize = null; + if (externalProperty != null) + { + node = (String) externalProperty.get(PersistenceProperties.KUNDERA_NODES); + port = (String) externalProperty.get(PersistenceProperties.KUNDERA_PORT); + poolSize = (String) externalProperty.get(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + } + if (node == null) + { + node = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_NODES); + } + if (port == null) + { + port = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_PORT); + } + if (poolSize == null) + { + poolSize = puMetadata.getProperties().getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + } + + if (StringUtils.isEmpty(poolSize)) + { + this.poolSize = DEFAULT_POOL_SIZE; + } + else + { + this.poolSize = Integer.parseInt(poolSize); + } + + onValidation(node, port); + + Configuration hadoopConf = new Configuration(); + hadoopConf.set("hbase.master", node + ":" + port); + + Connection conn = HBasePropertyReader.hsmd.getDataStore() != null ? HBasePropertyReader.hsmd.getDataStore() + .getConnection() : null; + if (conn != null && conn.getProperties() != null) + { + String zookeeperHost = conn.getProperties().getProperty("hbase.zookeeper.quorum"); + String zookeeperPort = conn.getProperties().getProperty("hbase.zookeeper.property.clientPort"); + hadoopConf.set("hbase.zookeeper.quorum", zookeeperHost != null ? zookeeperHost : node); + hadoopConf.set("hbase.zookeeper.property.clientPort", zookeeperPort != null ? zookeeperPort + : DEFAULT_ZOOKEEPER_PORT); + } + else + { + // in case "hbase.zookeeper.property.clientPort" is not supplied, it + // is different than hbase master port! + hadoopConf.set("hbase.zookeeper.quorum", node); + hadoopConf.set("hbase.zookeeper.property.clientPort", DEFAULT_ZOOKEEPER_PORT); + } + conf = new HBaseConfiguration(hadoopConf); + reader = new HBaseEntityReader(); + } + + @Override + protected Object createPoolOrConnection() + { + hTablePool = new HTablePool(conf, poolSize); + return hTablePool; + } + + @Override + protected Client instantiateClient(String persistenceUnit) + { + return new HBaseClient(indexManager, conf, hTablePool, reader, persistenceUnit, externalProperties, clientMetadata); + } + + @Override + public boolean isThreadSafe() + { + return true; + } + + @Override + public void destroy() + { + // TODO destroy pool + // hTablePool = null; + + // indexManager.close(); + if (schemaManager != null) + { + schemaManager.dropSchema(); + } + externalProperties = null; + schemaManager = null; + } + + @Override + public SchemaManager getSchemaManager(Map externalProperty) + { + setExternalProperties(externalProperty); + if (schemaManager == null) + { + initializePropertyReader(); + schemaManager = new HBaseSchemaManager(HBaseClientFactory.class.getName(), externalProperty); + } + return schemaManager; + } + + /** + * + */ + private void initializePropertyReader() + { + if (propertyReader == null) + { + propertyReader = new HBasePropertyReader(externalProperties); + propertyReader.read(getPersistenceUnit()); + } + } + + @Override + protected void initializeLoadBalancer(String loadBalancingPolicyName) + { + throw new UnsupportedOperationException("Load balancing feature is not supported in " + + this.getClass().getSimpleName()); + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientProperties.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientProperties.java new file mode 100644 index 000000000..6ed900c97 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseClientProperties.java @@ -0,0 +1,59 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.hbase; + +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.filter.Filter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientPropertiesSetter; + +/** + * HBase implementation of {@link ClientPropertiesSetter} + * + * @author amresh.singh + */ +class HBaseClientProperties +{ + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(HBaseClientProperties.class); + + private static final String FILTER = "hbase.filter"; + + public void populateClientProperties(Client client, Map properties) + { + HBaseClient hbaseClient = (HBaseClient) client; + + if (properties != null) + { + for (String key : properties.keySet()) + { + Object value = properties.get(key); + if (key.equals(FILTER) && value instanceof Filter) + { + hbaseClient.setFilter((Filter) value); + } + + // Add more + } + } + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseConstants.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseConstants.java new file mode 100644 index 000000000..256e0569c --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseConstants.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +/** + * Holds constants for kundera-hbase module + * + * @author Kuldeep Mishra + * + */ +public final class HBaseConstants +{ + public static final String CF_DEFS = "cf.defs"; + + public static final String ZOOKEEPER_PORT = "zookeeper.port"; + + public static final String ZOOKEEPER_HOST = "zookeeper.host"; +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseData.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseData.java new file mode 100644 index 000000000..73cf3a91c --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseData.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.util.Collections; +import java.util.List; + +import org.apache.hadoop.hbase.KeyValue; + +import com.impetus.kundera.DataWrapper; + +/** + * The Class HBaseData. + * + * @author impetus + */ +public class HBaseData implements DataWrapper +{ + + /** The column family. */ + private String columnFamily; + + /** The row key. */ + private byte[] rowKey; + + /** The columns. */ + private List columns; + + /** + * constructor with fields. + * + * @param columnFamily + * HBase column family + * @param rowKey + * Row key + */ + public HBaseData(String columnFamily, byte[] rowKey) + { + this.columnFamily = columnFamily; + this.rowKey = rowKey; + } + + /** + * Instantiates a new h base data. + * + * @param rowKey + * the row key + */ + public HBaseData(byte[] rowKey) + { + this.rowKey = rowKey; + } + + /** + * Getter column family. + * + * @return columnFamily column family + */ + public String getColumnFamily() + { + return columnFamily; + } + + /** + * Getter for row key. + * + * @return rowKey + */ + public byte[] getRowKey() + { + return rowKey; + } + + /** + * Getter for list of columns. + * + * @return list of columns + */ + public List getColumns() + { + return columns != null ? Collections.unmodifiableList(columns) : null; + } + + /** + * Sets the columns. + * + * @param columns + * the new columns + */ + public void setColumns(List columns) + { + this.columns = columns; + } + +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseEntityReader.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseEntityReader.java new file mode 100644 index 000000000..53ce2d2c2 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/HBaseEntityReader.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.util.List; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.AbstractEntityReader; +import com.impetus.kundera.persistence.EntityReader; + +/** + * The Class HBaseEntityReader. + * + * @author vivek.mishra + */ +public class HBaseEntityReader extends AbstractEntityReader implements EntityReader +{ + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.EntityReader#populateRelation(com.impetus + * .kundera.metadata.model.EntityMetadata, java.util.List, boolean, + * com.impetus.kundera.client.Client) + */ + @Override + public List populateRelation(EntityMetadata m, Client client, int maxResults) + { + throw new UnsupportedOperationException("Method is not supported"); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.EntityReader#findById(java.lang.String, + * com.impetus.kundera.metadata.model.EntityMetadata, java.util.List, + * com.impetus.kundera.client.Client) + */ + @Override + public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client) + { + return super.findById(primaryKey, m, client); + } + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Reader.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Reader.java new file mode 100644 index 000000000..d4e882272 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Reader.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.io.IOException; +import java.util.List; + +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.filter.Filter; + +// TODO: Auto-generated Javadoc +/** + * The Interface Reader. + */ +public interface Reader +{ + + /** + * Populates HBase data for given family name. + * + * @param hTable + * HBase table + * @param columnFamily + * HBase column family + * @param rowKey + * HBase row key. + * @param filter + * the filter + * @return HBase data wrapper containing all column names along with values. + * @throws IOException + * Signals that an I/O exception has occurred. + */ + List LoadData(HTableInterface hTable, String columnFamily, Object rowKey, Filter filter, + String... columns) throws IOException; + + /** + * Load data. + * + * @param hTable + * the h table + * @param rowKey + * the row key + * @param filter + * the filter + * @return the h base data + * @throws IOException + * Signals that an I/O exception has occurred. + */ + List LoadData(HTableInterface hTable, Object rowKey, Filter filter, String... columns) + throws IOException; + + /** + * Load all. + * + * @param hTable + * the h table + * @param filter + * the filter + * @param startRow + * the start row + * @param endRow + * the end row + * @param columns + * @return the list + * @throws IOException + * Signals that an I/O exception has occurred. + */ + List loadAll(HTableInterface hTable, Filter filter, byte[] startRow, byte[] endRow, String columnFamily, + String qualifier, String[] columns) throws IOException; + + /** + * Scan row keys. + * + * @param hTable + * the h table + * @param filter + * the filter + * @param columnFamilyName + * the columnFamily Name + * @param columnName + * the column Name + * @return object array + * @throws IOException + * Signals that an I/O exception has occurred. + */ + Object[] scanRowKeys(final HTableInterface hTable, final Filter filter, final String columnFamilyName, + final String columnName, final Class rowKeyClazz) throws IOException; +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Writer.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Writer.java new file mode 100644 index 000000000..29ba7c633 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/Writer.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.metamodel.Attribute; + +import org.apache.hadoop.hbase.client.HTableInterface; + +import com.impetus.client.hbase.admin.HBaseDataHandler.HBaseDataWrapper; +import com.impetus.kundera.db.RelationHolder; + +/** + * HBase data writer. + * + * @author impetus + */ +public interface Writer +{ + + /** + * Write column. + * + * @param htable + * the htable + * @param columnFamily + * the column family + * @param rowKey + * the row key + * @param column + * the column + * @param columnObj + * the column obj + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeColumn(HTableInterface htable, String columnFamily, Object rowKey, Attribute column, Object columnObj) + throws IOException; + + /** + * Writes a column family with name columnFamily, into a table + * whose columns are columns. + * + * @param htable + * the htable + * @param columnFamily + * Column Family Name + * @param rowKey + * Row Key + * @param columns + * Columns for a given column family + * @param columnFamilyObj + * the column family obj + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeColumns(HTableInterface htable, String columnFamily, Object rowKey, Set columns, + Object columnFamilyObj) throws IOException; + + /** + * Writes Columns columns into a given table. Each columns is + * written in their own column family(name same as column name) + * + * @param htable + * the htable + * @param rowKey + * the row key + * @param columns + * Columns of a given table (No column family given) + * @param entity + * the entity + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeColumns(HTableInterface htable, Object rowKey, Set columns, Object entity) throws IOException; + + /** + * Write relations. + * + * @param htable + * the htable + * @param rowKey + * the row key + * @param containsEmbeddedObjectsOnly + * the contains embedded objects only + * @param relations + * the relations + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeRelations(HTableInterface htable, Object rowKey, boolean containsEmbeddedObjectsOnly, + List relations) throws IOException; + + /** + * Writes foreign keys along with a database table. They are stored into a + * column family named FKey-TO. Each column corresponds to foreign key field + * name and values are actual foreign keys (separated by ~ if applicable) + * + * @param hTable + * the h table + * @param rowKey + * the row key + * @param foreignKeyMap + * the foreign key map + * @throws IOException + * Signals that an I/O exception has occurred. + * @deprecated + */ + public void writeForeignKeys(HTableInterface hTable, String rowKey, Map> foreignKeyMap) + throws IOException; + + /** + * Writes columns data to HBase table, supplied as a map in Key/ value pair; + * key and value representing column name and value respectively. + * + * @param htable + * the htable + * @param rowKey + * the row key + * @param columns + * the columns + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeColumns(HTableInterface htable, Object rowKey, Map columns) throws IOException; + + /** + * Delete. + * + * @param hTable + * the h table + * @param rowKey + * the row key + * @param columnFamily + * the column family + */ + void delete(HTableInterface hTable, Object rowKey, String columnFamily); + + /** + * method to perform batch insert/update. + * + * @param rows + * data rows + * @throws IOException + * throws io exception. + */ + void persistRows(Map> rows) throws IOException; +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/DataHandler.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/DataHandler.java new file mode 100644 index 000000000..acf0883a2 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/DataHandler.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.admin; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; + +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Data handler for HBase queries. + * + * @author vivek.mishra + */ + +public interface DataHandler +{ + + /** + * Creates a HBase table. + * + * @param tableName + * table name. + * @param colFamily + * column family. + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void createTableIfDoesNotExist(String tableName, String... colFamily) throws IOException; + + /** + * Populates data for give column family, column name, and HBase table name. + * + * @param tableName + * the table name + * @param clazz + * the clazz + * @param m + * the m + * @param rowKey + * the row key + * @param f + * @param relationNames + * the relation names + * @return the object + * @throws IOException + * Signals that an I/O exception has occurred. + */ + List readData(String tableName, Class clazz, EntityMetadata m, Object rowKey, List relatationNames, + FilterList f, String... columns) throws IOException; + + /** + * Populates data for give column family, column name, and HBase table name. + * + * @param tableName + * the table name + * @param clazz + * the clazz + * @param m + * the m + * @param rowKey + * the row key + * @param relationNames + * the relation names + * @return the object + * @throws IOException + * Signals that an I/O exception has occurred. + */ + List readAll(String tableName, Class clazz, EntityMetadata m, List rowKeys, List relatationNames, + String... columns) throws IOException; + + /** + * @param tableName + * @param clazz + * @param m + * @param relationNames + * @param startRow + * @param endRow + * @param columns + * @param f + * @return + */ + List readDataByRange(String tableName, Class clazz, EntityMetadata m, byte[] startRow, byte[] endRow, + String[] columns, FilterList f) throws IOException; + + /** + * Write data. + * + * @param tableName + * the table name + * @param m + * the m + * @param entity + * the entity + * @param rowId + * the row id + * @param relations + * the relations + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeData(String tableName, EntityMetadata m, Object entity, Object rowId, List relations) + throws IOException; + + /** + * Writes data into Join Table. + * + * @param tableName + * the table name + * @param rowId + * the row id + * @param columns + * the columns + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void writeJoinTableData(String tableName, Object rowId, Map columns) throws IOException; + + /** + * Retrieves a list of foreign keys from the join table for a given row key. + * + * @param + * the element type + * @param joinTableName + * the join table name + * @param rowKey + * the row key + * @param inverseJoinColumnName + * the inverse join column name + * @return the foreign keys from join table + */ + List getForeignKeysFromJoinTable(String joinTableName, Object rowKey, String inverseJoinColumnName); + + /** + * Retrieves a list of parent entity from join table.. + * + * @param + * @param parentMetadata + * @param joinTableName + * @param joinColumnName + * @param inverseJoinColumnName + * @param childId + * @return + */ + List findParentEntityFromJoinTable(EntityMetadata parentMetadata, String joinTableName, + String joinColumnName, String inverseJoinColumnName, Object childId); + + /** + * Shutdown. + */ + void shutdown(); + + /** + * Delete specific row. + * + * @param rowKey + * the row key + * @param tableName + * the table name + * @throws IOException + * Signals that an I/O exception has occurred. + */ + void deleteRow(Object rowKey, String tableName) throws IOException; + + Object[] scanRowyKeys(FilterList filterList, String tableName, String columnFamilyName, String columnName, + Class rowKeyClazz) throws IOException; +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/HBaseDataHandler.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/HBaseDataHandler.java new file mode 100644 index 000000000..2607e3752 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/admin/HBaseDataHandler.java @@ -0,0 +1,1167 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.admin; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.MasterNotRunningException; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.HTablePool; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; +import org.apache.hadoop.hbase.util.Bytes; +import org.jboss.netty.util.internal.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.HBaseData; +import com.impetus.client.hbase.Reader; +import com.impetus.client.hbase.Writer; +import com.impetus.client.hbase.service.HBaseReader; +import com.impetus.client.hbase.service.HBaseWriter; +import com.impetus.client.hbase.utils.HBaseUtils; +import com.impetus.kundera.Constants; +import com.impetus.kundera.KunderaException; +import com.impetus.kundera.cache.ElementCollectionCacheManager; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * The Class HBaseDataHandler. + * + * @author vivek.mishra + */ +public class HBaseDataHandler implements DataHandler +{ + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(HBaseDataHandler.class); + + /** The admin. */ + private HBaseAdmin admin; + + /** The conf. */ + private HBaseConfiguration conf; + + /** The h table pool. */ + private HTablePool hTablePool; + + /** The hbase reader. */ + private Reader hbaseReader = new HBaseReader(); + + /** The hbase writer. */ + private Writer hbaseWriter = new HBaseWriter(); + + private FilterList filter = null; + + private Map filters = new ConcurrentHashMap(); + + /** + * Instantiates a new h base data handler. + * + * @param conf + * the conf + * @param hTablePool + * the h table pool + */ + public HBaseDataHandler(HBaseConfiguration conf, HTablePool hTablePool) + { + try + { + this.conf = conf; + this.hTablePool = hTablePool; + this.admin = new HBaseAdmin(conf); + } + catch (Exception e) + { + // TODO We need a generic ExceptionTranslator + throw new PersistenceException(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#createTableIfDoesNotExist( + * java.lang.String, java.lang.String[]) + */ + @Override + public void createTableIfDoesNotExist(final String tableName, final String... colFamily) + throws MasterNotRunningException, IOException + { + if (!admin.tableExists(Bytes.toBytes(tableName))) + { + HTableDescriptor htDescriptor = new HTableDescriptor(tableName); + for (String columnFamily : colFamily) + { + HColumnDescriptor familyMetadata = new HColumnDescriptor(columnFamily); + htDescriptor.addFamily(familyMetadata); + } + admin.createTable(htDescriptor); + } + } + + /** + * Adds the column family to table. + * + * @param tableName + * the table name + * @param columnFamilyName + * the column family name + * @throws IOException + * Signals that an I/O exception has occurred. + */ + private void addColumnFamilyToTable(String tableName, String columnFamilyName) throws IOException + { + HColumnDescriptor cfDesciptor = new HColumnDescriptor(columnFamilyName); + + try + { + if (admin.tableExists(tableName)) + { + + // Before any modification to table schema, it's necessary to + // disable it + if (!admin.isTableEnabled(tableName)) + { + admin.enableTable(tableName); + } + HTableDescriptor descriptor = admin.getTableDescriptor(tableName.getBytes()); + boolean found = false; + for (HColumnDescriptor hColumnDescriptor : descriptor.getColumnFamilies()) + { + if (hColumnDescriptor.getNameAsString().equalsIgnoreCase(columnFamilyName)) + found = true; + } + if (!found) + { + + if (admin.isTableEnabled(tableName)) + { + admin.disableTable(tableName); + } + + admin.addColumn(tableName, cfDesciptor); + + // Enable table once done + admin.enableTable(tableName); + } + } + else + { + log.warn("Table {} doesn't exist, so no question of adding column family {} to it!", tableName, + columnFamilyName); + } + } + catch (IOException e) + { + log.error("Error while adding column family {}, to table{} . ", columnFamilyName, tableName); + throw e; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#readData(java.lang.String, + * java.lang.Class, com.impetus.kundera.metadata.model.EntityMetadata, + * java.lang.String, java.util.List) + */ + @Override + public List readData(final String tableName, Class clazz, EntityMetadata m, final Object rowKey, + List relationNames, FilterList f, String... columns) throws IOException + { + + List output = null; + + Object entity = null; + + HTableInterface hTable = null; + + hTable = gethTable(tableName); + + if (getFilter(tableName) != null) + { + if (f == null) + { + f = new FilterList(); + } + f.addFilter(getFilter(tableName)); + } + + // Load raw data from HBase + List results = hbaseReader.LoadData(hTable, rowKey, f, columns); + output = onRead(tableName, clazz, m, output, hTable, entity, relationNames, results); + return output; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#readData(java.lang.String, + * java.lang.Class, com.impetus.kundera.metadata.model.EntityMetadata, + * java.lang.String, java.util.List) + */ + @Override + public List readAll(final String tableName, Class clazz, EntityMetadata m, final List rowKey, + List relationNames, String... columns) throws IOException + { + + List output = null; + + Object entity = null; + + HTableInterface hTable = null; + + hTable = gethTable(tableName); + + // Load raw data from HBase + List results = ((HBaseReader) hbaseReader).loadAll(hTable, rowKey, tableName, columns); + output = onRead(tableName, clazz, m, output, hTable, entity, relationNames, results); + return output; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#readDataByRange(java.lang. + * String, java.lang.Class, + * com.impetus.kundera.metadata.model.EntityMetadata, java.util.List, + * byte[], byte[]) + */ + @Override + public List readDataByRange(String tableName, Class clazz, EntityMetadata m, byte[] startRow, byte[] endRow, + String[] columns, FilterList f) throws IOException + { + List output = new ArrayList(); + HTableInterface hTable = null; + Object entity = null; + List relationNames = m.getRelationNames(); + + if (getFilter(tableName) != null) + { + if (f == null) + { + f = new FilterList(); + } + f.addFilter(getFilter(tableName)); + } + // Load raw data from HBase + hTable = gethTable(tableName); + List results = hbaseReader.loadAll(hTable, f, startRow, endRow, m.getTableName(), null, columns); + output = onRead(tableName, clazz, m, output, hTable, entity, relationNames, results); + + return output; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#writeData(java.lang.String, + * com.impetus.kundera.metadata.model.EntityMetadata, java.lang.Object, + * java.lang.String, java.util.List) + */ + @Override + public void writeData(String tableName, EntityMetadata m, Object entity, Object rowId, + List relations) throws IOException + { + HTableInterface hTable = gethTable(tableName); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + Set attributes = entityType.getAttributes(); + + HBaseDataWrapper columnWrapper = new HBaseDataWrapper(rowId, new java.util.HashSet(), entity, null); + List persistentData = new ArrayList(attributes.size()); + + preparePersistentData(tableName, entity, rowId, metaModel, attributes, columnWrapper, persistentData); + + hbaseWriter.writeColumns(hTable, columnWrapper.getRowKey(), columnWrapper.getColumns(), entity); + + for (HBaseDataWrapper wrapper : persistentData) + { + hbaseWriter.writeColumns(hTable, wrapper.getColumnFamily(), wrapper.getRowKey(), wrapper.getColumns(), + wrapper.getEntity()); + } + + // Persist relationships as a column in newly created Column family by + // Kundera + boolean containsEmbeddedObjectsOnly = columnWrapper.getColumns().isEmpty() && persistentData.isEmpty(); + + if (relations != null && !relations.isEmpty()) + { + hbaseWriter.writeRelations(hTable, rowId, containsEmbeddedObjectsOnly, relations); + } + puthTable(hTable); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#writeJoinTableData(java.lang + * .String, java.lang.String, java.util.Map) + */ + @Override + public void writeJoinTableData(String tableName, Object rowId, Map columns) throws IOException + { + HTableInterface hTable = gethTable(tableName); + + hbaseWriter.writeColumns(hTable, rowId, columns); + + puthTable(hTable); + + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#getForeignKeysFromJoinTable + * (java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public List getForeignKeysFromJoinTable(String joinTableName, Object rowKey, String inverseJoinColumnName) + { + List foreignKeys = new ArrayList(); + + HTableInterface hTable = null; + + // Load raw data from Join Table in HBase + try + { + hTable = gethTable(joinTableName); + + List results = hbaseReader.LoadData(hTable, joinTableName, rowKey, getFilter(joinTableName)); + + // assuming rowKey is not null. + if (results != null) + { + + HBaseData data = results.get(0); + + List hbaseValues = data.getColumns(); + if (hbaseValues != null) + { + for (KeyValue colData : hbaseValues) + { + String hbaseColumn = Bytes.toString(colData.getQualifier()); + String hbaseColumnFamily = Bytes.toString(colData.getFamily()); + + if (hbaseColumnFamily.equals(joinTableName) && hbaseColumn.startsWith(inverseJoinColumnName)) + { + byte[] val = colData.getValue(); + + // TODO : Because no attribute class is present, so + // cannot be done. + String hbaseColumnValue = Bytes.toString(val); + + foreignKeys.add((E) hbaseColumnValue); + } + } + } + } + } + catch (IOException e) + { + return foreignKeys; + } + finally + { + try + { + if (hTable != null) + { + puthTable(hTable); + } + } + catch (IOException e) + { + + // Do nothing. + } + } + return foreignKeys; + } + + /** + * Selects an HTable from the pool and returns. + * + * @param tableName + * Name of HBase table + * @return the h table + * @throws IOException + * Signals that an I/O exception has occurred. + */ + public HTableInterface gethTable(final String tableName) throws IOException + { + return hTablePool.getTable(tableName); + } + + /** + * Puts HTable back into the HBase table pool. + * + * @param hTable + * HBase Table instance + */ + private void puthTable(HTableInterface hTable) throws IOException + { + hTablePool.putTable(hTable); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.hbase.admin.DataHandler#shutdown() + */ + @Override + public void shutdown() + { + + // TODO: Shutting down admin actually shuts down HMaster, something we + // don't want. + // Devise a better way to release resources. + + /* + * try { + * + * admin.shutdown(); + * + * } catch (IOException e) { throw new RuntimeException(e.getMessage()); + * } + */ + } + + // TODO: Scope of performance improvement in this method + /** + * Populate entity from hbase data. + * + * @param entity + * the entity + * @param hbaseData + * the hbase data + * @param m + * the m + * @param rowKey + * the row key + * @param relationNames + * the relation names + * @return the object + */ + private Object populateEntityFromHbaseData(Object entity, HBaseData hbaseData, EntityMetadata m, Object rowKey, + List relationNames) + { + try + { + // Raw data retrieved from HBase for a particular row key (contains + // all column families) + List hbaseValues = hbaseData.getColumns(); + + Map relations = new HashMap(); + /* + * Populate columns data + */ + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + // List columns = m.getColumnsAsList(); + Set columns = entityType.getAttributes(); + // for (Column column : columns) + for (Attribute column : columns) + { + Class javaType = ((AbstractAttribute) column).getBindableJavaType(); + String key = ((AbstractAttribute) column).getJPAColumnName(); + if (metaModel.isEmbeddable(javaType)) + { + EmbeddableType columnFamily = metaModel.embeddable(javaType); + + Field columnFamilyFieldInEntity = (Field) column.getJavaMember(); + Class columnFamilyClass = columnFamilyFieldInEntity.getType(); + + // Get a name->field map for columns in this column family + Map columnNameToFieldMap = MetadataUtils.createColumnsFieldMap(m, columnFamily); + + // Column family can be either @Embedded or + // @EmbeddedCollection + if (Collection.class.isAssignableFrom(columnFamilyClass)) + { + + Field embeddedCollectionField = (Field) column.getJavaMember(); + Object[] embeddedObjectArr = new Object[hbaseValues.size()]; + Object embeddedObject = MetadataUtils.getEmbeddedGenericObjectInstance(embeddedCollectionField); + int prevCFNameCounter = 0; // Previous CF name counter + for (KeyValue colData : hbaseValues) + { + String cfInHbase = Bytes.toString(colData.getFamily()); + byte[] columnValue = colData.getValue(); + // Only populate those data from Hbase into entity + // that + // matches with column family name + // in the format # + if (!cfInHbase.startsWith(key)) + { + if (relationNames != null && relationNames.contains(cfInHbase) + && columnValue.length != 0) + { + relations.put(cfInHbase, + getObjectFromByteArray(entityType, columnValue, cfInHbase, m)); + } + continue; + + } + + String cfNamePostfix = MetadataUtils.getEmbeddedCollectionPostfix(cfInHbase); + int cfNameCounter = Integer.parseInt(cfNamePostfix); + if (cfNameCounter != prevCFNameCounter) + { + prevCFNameCounter = cfNameCounter; + + // Fresh embedded object for the next column + // family + // in collection + embeddedObject = MetadataUtils + .getEmbeddedGenericObjectInstance(embeddedCollectionField); + } + + // Set Hbase data into the embedded object + setHBaseDataIntoObject(colData, columnFamilyFieldInEntity, columnNameToFieldMap, + embeddedObject); + + embeddedObjectArr[cfNameCounter] = embeddedObject; + + // Save embedded object into Cache, needed while + // updation and deletion + ElementCollectionCacheManager.getInstance().addElementCollectionCacheMapping(rowKey, + embeddedObject, cfInHbase); + } + + // Collection to hold column family objects + Collection embeddedCollection = MetadataUtils + .getEmbeddedCollectionInstance(embeddedCollectionField); + embeddedCollection.addAll(Arrays.asList(embeddedObjectArr)); + embeddedCollection.removeAll(Collections.singletonList(null)); + embeddedObjectArr = null; // Eligible for GC + + // Now, set the embedded collection into entity + if (embeddedCollection != null && !embeddedCollection.isEmpty()) + { + PropertyAccessorHelper.set(entity, embeddedCollectionField, embeddedCollection); + } + } + else + { + Object columnFamilyObj = columnFamilyClass.newInstance(); + + for (KeyValue colData : hbaseValues) + { + String cfInHbase = Bytes.toString(colData.getFamily()); + + byte[] columnValue = colData.getValue(); + if (relationNames != null && relationNames.contains(cfInHbase) && columnValue.length != 0) + { + relations.put(cfInHbase, getObjectFromByteArray(entityType, columnValue, cfInHbase, m)); + } + // Set Hbase data into the column family object + + String colName = Bytes.toString(colData.getQualifier()); + + // Get Column from metadata + Field columnField = columnNameToFieldMap.get(colName); + if (columnField != null && columnValue.length != 0) + { + if (columnFamilyFieldInEntity.isAnnotationPresent(Embedded.class) + || columnFamilyFieldInEntity.isAnnotationPresent(ElementCollection.class)) + { + PropertyAccessorHelper.set(columnFamilyObj, columnField, + HBaseUtils.fromBytes(columnValue, columnField.getType())); + } + else + { + columnFamilyObj = getObjectFromByteArray(entityType, columnValue, cfInHbase, m); + } + } + } + PropertyAccessorHelper.set(entity, columnFamilyFieldInEntity, columnFamilyObj); + } + } + else if (!column.getName().equals(m.getIdAttribute().getName())) + { + Field columnField = (Field) column.getJavaMember(); + String columnName = ((AbstractAttribute) column).getJPAColumnName(); + + for (KeyValue colData : hbaseValues) + { + String hbaseColumn = Bytes.toString(colData.getQualifier()); + String colName = hbaseColumn; + byte[] columnValue = colData.getValue(); + if (relationNames != null && relationNames.contains(colName) && columnValue.length != 0) + { + relations.put(colName, getObjectFromByteArray(entityType, columnValue, colName, m)); + } + else if (colName != null && colName.equalsIgnoreCase(columnName.toLowerCase()) + && columnValue.length != 0) + { + PropertyAccessorHelper.set(entity, columnField, + HBaseUtils.fromBytes(columnValue, columnField.getType())); + } + } + } + } + if (!relations.isEmpty()) + { + return new EnhanceEntity(entity, rowKey, relations); + } + return entity; + } + catch (PropertyAccessException e1) + { + throw new RuntimeException(e1); + } + catch (InstantiationException e1) + { + throw new RuntimeException(e1); + } + catch (IllegalAccessException e1) + { + throw new RuntimeException(e1); + } + } + + /** + * Sets the h base data into object. + * + * @param colData + * the col data + * @param columnFamilyField + * the column family field + * @param columnNameToFieldMap + * the column name to field map + * @param columnFamilyObj + * the column family obj + * @throws PropertyAccessException + * the property access exception + */ + private void setHBaseDataIntoObject(KeyValue colData, Field columnFamilyField, + Map columnNameToFieldMap, Object columnFamilyObj) throws PropertyAccessException + { + String colName = Bytes.toString(colData.getQualifier()); + byte[] columnValue = colData.getValue(); + + // Get Column from metadata + Field columnField = columnNameToFieldMap.get(colName); + if (columnField != null) + { + if (columnFamilyField.isAnnotationPresent(Embedded.class) + || columnFamilyField.isAnnotationPresent(ElementCollection.class)) + { + PropertyAccessorHelper.set(columnFamilyObj, columnField, columnValue); + } + else + { + columnFamilyObj = HBaseUtils.fromBytes(columnValue, columnFamilyObj.getClass()); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.admin.DataHandler#deleteRow(java.lang.String, + * java.lang.String) + */ + public void deleteRow(Object rowKey, String tableName) throws IOException + { + hbaseWriter.delete(gethTable(tableName), rowKey, tableName); + } + + @Override + public List findParentEntityFromJoinTable(EntityMetadata parentMetadata, String joinTableName, + String joinColumnName, String inverseJoinColumnName, Object childId) + { + throw new PersistenceException("Not applicable for HBase"); + } + + /** + * Set filter to data handler. + * + * @param filter + * hbase filter. + */ + public void setFilter(Filter filter) + { + if (this.filter == null) + { + this.filter = new FilterList(); + } + if (filter != null) + { + this.filter.addFilter(filter); + } + } + + public void addFilter(final String columnFamily, Filter filter) + { + FilterList filterList = this.filters.get(columnFamily); + if (filterList == null) + { + filterList = new FilterList(); + } + if (filter != null) + { + filterList.addFilter(filter); + } + this.filters.put(columnFamily, filterList); + } + + /** + * + * @param tableName + * @param clazz + * @param m + * @param startRow + * @param endRow + * @param output + * @param hTable + * @param entity + * @param relationNames + * @param results + * @return + * @throws IOException + */ + private List onRead(String tableName, Class clazz, EntityMetadata m, List output, HTableInterface hTable, + Object entity, List relationNames, List results) throws IOException + { + try + { + // Populate raw data from HBase into entity + + if (results != null) + { + for (HBaseData data : results) + { + entity = clazz.newInstance(); // Entity Object + /* Set Row Key */ + PropertyAccessorHelper.setId(entity, m, HBaseUtils.fromBytes(m, data.getRowKey())); + + if (data.getColumns() != null) + { + entity = populateEntityFromHbaseData(entity, data, m, null, relationNames); + if (output == null) + { + output = new ArrayList(); + } + } + output.add(entity); + } + } + } + catch (InstantiationException iex) + { + log.error("Error while creating an instance of {} .", clazz); + throw new PersistenceException(iex); + } + catch (IllegalAccessException iaex) + { + log.error("Illegal Access while reading data from {}, Caused by: .", tableName, iaex); + throw new PersistenceException(iaex); + } + catch (Exception e) + { + log.error("Error while creating an instance of {}, Caused by: .", clazz, e); + throw new PersistenceException(e); + } + finally + { + if (hTable != null) + { + puthTable(hTable); + } + } + return output; + } + + /** + * @author vivek.mishra + * + */ + public static class HBaseDataWrapper + { + Object rowKey; + + private Set columns; + + private Object entity; + + private String columnFamily; + + /** + * @param rowKey + * @param columns + * @param entity + * @param columnFamily + */ + public HBaseDataWrapper(Object rowKey, Set columns, Object entity, String columnFamily) + { + super(); + this.rowKey = rowKey; + this.columns = columns; + this.entity = entity; + this.columnFamily = columnFamily; + } + + /** + * @return the rowKey + */ + public Object getRowKey() + { + return rowKey; + } + + /** + * @return the columns + */ + public Set getColumns() + { + return columns; + } + + /** + * @return the entity + */ + public Object getEntity() + { + return entity; + } + + /** + * @return the columnFamily + */ + public String getColumnFamily() + { + return columnFamily; + } + + public void addColumn(Attribute column) + { + columns.add(column); + } + } + + public List scanData(Filter f, final String tableName, Class clazz, EntityMetadata m, String columnFamily, + String qualifier) throws IOException, InstantiationException, IllegalAccessException + { + List returnedResults = new ArrayList(); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + Set attributes = entityType.getAttributes(); + String[] columns = new String[attributes.size() - 1]; + int count = 0; + boolean isCollection = false; + for (Attribute attr : attributes) + { + if (!attr.isCollection() && !attr.getName().equalsIgnoreCase(m.getIdAttribute().getName())) + { + columns[count++] = ((AbstractAttribute) attr).getJPAColumnName(); + } + else if (attr.isCollection()) + { + isCollection = true; + break; + } + } + List results = hbaseReader.loadAll(gethTable(tableName), f, null, null, m.getTableName(), + isCollection ? qualifier : null, null); + if (results != null) + { + for (HBaseData row : results) + { + Object entity = clazz.newInstance();// Entity Object + /* Set Row Key */ + PropertyAccessorHelper.setId(entity, m, HBaseUtils.fromBytes(m, row.getRowKey())); + + returnedResults.add(populateEntityFromHbaseData(entity, row, m, row.getRowKey(), m.getRelationNames())); + } + } + return returnedResults; + } + + @Override + public Object[] scanRowyKeys(FilterList filterList, String tableName, String columnFamilyName, String columnName, + final Class rowKeyClazz) throws IOException + { + HTableInterface hTable = null; + hTable = gethTable(tableName); + return hbaseReader.scanRowKeys(hTable, filterList, columnFamilyName, columnName, rowKeyClazz); + } + + private Object getObjectFromByteArray(EntityType entityType, byte[] value, String jpaColumnName, EntityMetadata m) + { + if (jpaColumnName != null) + { + String fieldName = m.getFieldName(jpaColumnName); + if (fieldName != null) + { + Attribute attribute = fieldName != null ? entityType.getAttribute(fieldName) : null; + + EntityMetadata relationMetadata = KunderaMetadataManager.getEntityMetadata(attribute.getJavaType()); + Object colValue = PropertyAccessorHelper.getObject(relationMetadata.getIdAttribute().getJavaType(), + (byte[]) value); + return colValue; + } + } + log.warn("No value found for column {}, returning null.", jpaColumnName); + return null; + } + + /** + * + * @param tableName + * @param entity + * @param rowId + * @param metaModel + * @param attributes + * @param columnWrapper + * @param persistentData + * @return + * @throws IOException + */ + public void preparePersistentData(String tableName, Object entity, Object rowId, MetamodelImpl metaModel, + Set attributes, HBaseDataWrapper columnWrapper, List persistentData) + throws IOException + { + for (Attribute column : attributes) + { + String fieldName = ((AbstractAttribute) column).getJPAColumnName(); + + Class javaType = ((AbstractAttribute) column).getBindableJavaType(); + if (metaModel.isEmbeddable(javaType)) + { + String columnFamilyName = ((AbstractAttribute) column).getJPAColumnName(); + Field columnFamilyField = (Field) column.getJavaMember(); + Object columnFamilyObject = null; + try + { + columnFamilyObject = PropertyAccessorHelper.getObject(entity, columnFamilyField); + } + catch (PropertyAccessException paex) + { + log.error("Error while getting {}, field from entity {} .", columnFamilyName, entity); + throw new KunderaException(paex); + } + + if (columnFamilyObject != null) + { + // continue; + Set columns = metaModel.embeddable(javaType).getAttributes(); + if (column.isCollection()) + { + String dynamicCFName = null; + + ElementCollectionCacheManager ecCacheHandler = ElementCollectionCacheManager.getInstance(); + // Check whether it's first time insert or updation + if (ecCacheHandler.isCacheEmpty()) + { // First time insert + int count = 0; + for (Object obj : (Collection) columnFamilyObject) + { + dynamicCFName = columnFamilyName + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + count; + addColumnFamilyToTable(tableName, dynamicCFName); + + persistentData.add(new HBaseDataWrapper(rowId, columns, obj, dynamicCFName)); + count++; + } + } + else + { + // Updation + // Check whether this object is already in cache, + // which + // means we already have a column family with that + // name + // Otherwise we need to generate a fresh column + // family + // name + int lastEmbeddedObjectCount = ecCacheHandler.getLastElementCollectionObjectCount(rowId); + for (Object obj : (Collection) columnFamilyObject) + { + dynamicCFName = ecCacheHandler.getElementCollectionObjectName(rowId, obj); + if (dynamicCFName == null) + { // Fresh row + dynamicCFName = columnFamilyName + Constants.EMBEDDED_COLUMN_NAME_DELIMITER + + (++lastEmbeddedObjectCount); + + } + addColumnFamilyToTable(tableName, dynamicCFName); + persistentData.add(new HBaseDataWrapper(rowId, columns, obj, dynamicCFName)); + } + // Clear embedded collection cache for GC + ecCacheHandler.clearCache(); + } + } + else + { + // Write Column family which was Embedded object in + // entity + if (columnFamilyField.isAnnotationPresent(Embedded.class)) + { + persistentData.add(new HBaseDataWrapper(rowId, columns, columnFamilyObject, tableName)); + } + else + { + persistentData.add(new HBaseDataWrapper(rowId, columns, columnFamilyObject, tableName)); + } + } + } + } + else if (!column.isAssociation()) + { + columnWrapper.addColumn(column); + } + } + } + + /** + * @param data + * @throws IOException + */ + public void batch_insert(Map> data) throws IOException + { + hbaseWriter.persistRows(data); + } + + public void setFetchSize(final int fetchSize) + { + ((HBaseReader) hbaseReader).setFetchSize(fetchSize); + } + + public Object next(EntityMetadata m) + { + Object entity = null; + HBaseData result = ((HBaseReader) hbaseReader).next(); + List results = new ArrayList(); + List output = new ArrayList(); + results.add(result); + try + { + output = onRead(m.getTableName(), m.getEntityClazz(), m, output, gethTable(m.getTableName()), entity, + m.getRelationNames(), results); + } + catch (IOException e) + { + log.error("Error during finding next record, Caused by: .", e); + throw new KunderaException(e); + } + + return output != null && !output.isEmpty() ? output.get(0) : output; + } + +// public List next(EntityMetadata m, final int chunkSize) +// { +// Object entity = null; +// List results = ((HBaseReader) hbaseReader).next(chunkSize); +// List output = new ArrayList(); +// try +// { +// output = onRead(m.getTableName(), m.getEntityClazz(), m, output, gethTable(m.getTableName()), entity, +// m.getRelationNames(), results); +// } +// catch (IOException e) +// { +// log.error("Error during finding next record, Caused by: .", e); +// throw new KunderaException(e); +// } +// return output != null ? output : new ArrayList(); +// } + + public boolean hasNext() + { + return ((HBaseReader) hbaseReader).hasNext(); + } + + public void reset() + { + resetFilter(); + ((HBaseReader) hbaseReader).reset(); + } + + public void resetFilter() + { + filter = null; + filters = new ConcurrentHashMap(); + } + + public HBaseDataHandler getHandle() + { + HBaseDataHandler handler = new HBaseDataHandler(this.conf, this.hTablePool); + handler.filter = this.filter; + handler.filters = this.filters; + return handler; + } + + private Filter getFilter(final String columnFamily) + { + FilterList filter = filters.get(columnFamily); + if (filter == null) + { + return this.filter; + } + if (this.filter != null) + { + filter.addFilter(this.filter); + } + return filter; + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/config/HBasePropertyReader.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/config/HBasePropertyReader.java new file mode 100644 index 000000000..8defe9359 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/config/HBasePropertyReader.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.config; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.HBaseConstants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.AbstractPropertyReader; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection; +import com.impetus.kundera.configure.PropertyReader; + +/** + * HBase Property Reader reads hbase properties from property file + * {kundera-hbase.properties} and put it into hbase schema metadata. + * + * @author kuldeep.mishra + * + */ +public class HBasePropertyReader extends AbstractPropertyReader implements PropertyReader +{ + + /** + * The log instance. + */ + private static Logger log = LoggerFactory.getLogger(HBasePropertyReader.class); + + /** + * The Hbase schema metadata instance. + */ + public static HBaseSchemaMetadata hsmd; + + public HBasePropertyReader(Map externalProperties) + { + super(externalProperties); + hsmd = new HBaseSchemaMetadata(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.configure.PropertyReader#read(java.lang.String) + */ + + public void onXml(ClientProperties cp) + { + hsmd.onInitialize(); + if (cp != null) + { + hsmd.setClientProperties(cp); + } + } + + public class HBaseSchemaMetadata + { + /** + * zookeeper port. + */ + private String zookeeperPort = "2181"; + + /** + * zookeeper host. + */ + private String zookeeperHost; + + /** + * client properties. + */ + private ClientProperties clientProperties; + + /** + * + */ + private void onInitialize() + { + zookeeperHost = puMetadata != null ? puMetadata.getProperty(PersistenceProperties.KUNDERA_NODES) : null; + } + + /** + * @return the clientProperties + */ + public ClientProperties getClientProperties() + { + return clientProperties; + } + + /** + * @param clientProperties + * the clientProperties to set + */ + private void setClientProperties(ClientProperties clientProperties) + { + this.clientProperties = clientProperties; + } + + /** + * @return the zookeeper_port + */ + public String getZookeeperPort() + { + DataStore ds = getDataStore(); + if (ds != null && ds.getConnection() != null) + { + Connection conn = ds.getConnection(); + if (conn.getProperties() != null && !conn.getProperties().isEmpty()) + { + zookeeperPort = conn.getProperties().getProperty(HBaseConstants.ZOOKEEPER_PORT); + } + } + return zookeeperPort; + } + + /** + * @return the zookeeper_host + */ + public String getZookeeperHost() + { + DataStore ds = getDataStore(); + if (ds != null && ds.getConnection() != null) + { + Connection conn = ds.getConnection(); + if (conn.getProperties() != null && !conn.getProperties().isEmpty()) + { + zookeeperHost = conn.getProperties().getProperty(HBaseConstants.ZOOKEEPER_HOST); + } + } + return zookeeperHost; + } + + public DataStore getDataStore() + { + if (getClientProperties() != null && getClientProperties().getDatastores() != null) + { + for (DataStore dataStore : getClientProperties().getDatastores()) + { + if (dataStore.getName() != null && dataStore.getName().equalsIgnoreCase("hbase")) + { + return dataStore; + } + } + } + return null; + } + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/HBaseQuery.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/HBaseQuery.java new file mode 100644 index 000000000..8f2441c14 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/HBaseQuery.java @@ -0,0 +1,572 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.query; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; +import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.HBaseEntityReader; +import com.impetus.client.hbase.utils.HBaseUtils; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.query.KunderaQuery; +import com.impetus.kundera.query.KunderaQuery.FilterClause; +import com.impetus.kundera.query.QueryHandlerException; +import com.impetus.kundera.query.QueryImpl; + +/** + * Query implementation for HBase, translates JPQL into HBase Filters using + * {@link QueryTranslator}. + * + * @author vivek.mishra + * + */ +public class HBaseQuery extends QueryImpl +{ + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(HBaseQuery.class); + + /** + * Holds reference to entity reader. + */ + private EntityReader reader = new HBaseEntityReader(); + + /** + * Constructor using fields. + * + * @param query + * jpa query. + * @param persistenceDelegator + * persistence delegator interface. + */ + public HBaseQuery(String query, KunderaQuery kunderaQuery, PersistenceDelegator persistenceDelegator) + { + super(query, persistenceDelegator); + this.kunderaQuery = kunderaQuery; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.query.QueryImpl#populateEntities(com.impetus.kundera + * .metadata.model.EntityMetadata, com.impetus.kundera.client.Client) + */ + @Override + protected List populateEntities(EntityMetadata m, Client client) + { + List results = onQuery(m, client); + return results; + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.query.QueryImpl#recursivelyPopulateEntities(com.impetus + * .kundera.metadata.model.EntityMetadata, + * com.impetus.kundera.client.Client) + */ + @Override + protected List recursivelyPopulateEntities(EntityMetadata m, Client client) + { + // required in case of associated entities. + List ls = onQuery(m, client); + return setRelationEntities(ls, client, m); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#getReader() + */ + @Override + protected EntityReader getReader() + { + return reader; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#onExecuteUpdate() + */ + @Override + protected int onExecuteUpdate() + { + if (kunderaQuery.isDeleteUpdate()) + { + List result = getResultList(); + return result != null ? result.size() : 0; + } + return 0; + } + + /** + * Parses and translates query into HBase filter and invokes client's method + * to return list of entities. + * + * @param m + * Entity metadata + * @param client + * hbase client + * @return list of entities. + */ + private List onQuery(EntityMetadata m, Client client) + { + // Called only in case of standalone entity. + QueryTranslator translator = new QueryTranslator(); + translator.translate(getKunderaQuery(), m); + // start with 1 as first element is alias. + List columns = getTranslatedColumns(m, getKunderaQuery().getResult(), 1); + Map filter = translator.getFilter(); + if (translator.isFindById && (filter == null && columns == null)) + { + List results = new ArrayList(); + + Object output = client.find(m.getEntityClazz(), translator.rowKey); + if (output != null) + { + results.add(output); + } + return results; + } + if (translator.isFindById && filter == null && columns != null) + { + return ((HBaseClient) client).findByRange(m.getEntityClazz(), m, translator.rowKey, translator.rowKey, + columns.toArray(new String[columns.size()]), null); + } + +// MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata()); + if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + if (filter == null && !translator.isFindById) + { + // means complete scan without where clause, scan all records. + // findAll. + if (translator.isRangeScan()) + { + return ((HBaseClient) client).findByRange(m.getEntityClazz(), m, translator.getStartRow(), + translator.getEndRow(), columns.toArray(new String[columns.size()]), null); + } + else + { + return ((HBaseClient) client).findByRange(m.getEntityClazz(), m, null, null, + columns.toArray(new String[columns.size()]), null); + } + } + else + { + // means WHERE clause is present. + Filter f = null; + if (filter != null && filter.values() != null && !filter.values().isEmpty()) + { + f = filter.values().iterator().next(); + } + if (translator.isRangeScan()) + { + return ((HBaseClient) client).findByRange(m.getEntityClazz(), m, translator.getStartRow(), + translator.getEndRow(), columns.toArray(new String[columns.size()]), f); + } + else + { + // if range query. means query over id column. create range + // scan method. + + // else setFilter to client and invoke new method. find by + // query if isFindById is false! else invoke findById + return ((HBaseClient) client).findByQuery(m.getEntityClazz(), m, f, + columns.toArray(new String[columns.size()])); + } + } + } + else + { + List results = null; + return populateUsingLucene(m, client, results, null); + } + } + + /** + * @param columns + * @param m + * @return + */ + private List getTranslatedColumns(EntityMetadata m, String[] columns, final int startWith) + { + List translatedColumns = new ArrayList(); + if (columns != null) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entity = metaModel.entity(m.getEntityClazz()); + for (int i = startWith; i < columns.length; i++) + { + if (columns[i] != null) + { + String fieldName = null; + String embeddedFieldName = null; + // used string tokenizer to check for embedded column. + StringTokenizer stringTokenizer = new StringTokenizer(columns[i], "."); + // if need to select embedded columns + if (stringTokenizer.countTokens() > 1) + { + fieldName = stringTokenizer.nextToken(); + embeddedFieldName = stringTokenizer.nextToken(); + Attribute col = entity.getAttribute(fieldName); // get + // embedded + // column + EmbeddableType embeddableType = metaModel.embeddable(col.getJavaType()); // get + // embeddable + // type + Attribute attribute = embeddableType.getAttribute(embeddedFieldName); + translatedColumns.add(((AbstractAttribute) attribute).getJPAColumnName()); + } + else + { + // For all columns + fieldName = columns[i]; + Attribute col = entity.getAttribute(fieldName); + onEmbeddable(translatedColumns, metaModel, col, + metaModel.isEmbeddable(((AbstractAttribute) col).getBindableJavaType())); + } + } + } + } + return translatedColumns; + } + + /** + * @param translatedColumns + * @param metaModel + * @param col + */ + private void onEmbeddable(List translatedColumns, MetamodelImpl metaModel, Attribute col, + boolean isEmbeddable) + { + if (isEmbeddable) + { + EmbeddableType embeddableType = metaModel.embeddable(col.getJavaType()); + + Set attributes = embeddableType.getAttributes(); + + for (Attribute attribute : attributes) + { + translatedColumns.add(((AbstractAttribute) attribute).getJPAColumnName()); + } + } + else + { + translatedColumns.add(((AbstractAttribute) col).getJPAColumnName()); + } + } + + /** + * Query translator to translate JPQL into HBase query definition(e.g. + * Filter/Filterlist) + * + * @author vivek.mishra + * + */ + class QueryTranslator + { + /* filter list to hold collection for applied filters */ + private List filterList; + + /* Returns true, if intended for id column */ + private boolean isIdColumn; + + /* + * byte[] value for start row, in case of range query, else will contain + * null. + */ + private byte[] startRow; + + /* + * byte[] value for end row, in case of range query, else will contain + * null. + */ + private byte[] endRow; + + /* is true, if query intended for row key equality. */ + private boolean isFindById; + + /* row key value. */ + byte[] rowKey; + + /** + * Translates kundera query into collection of to be applied HBase + * filter/s. + * + * @param query + * kundera query. + * @param m + * entity's metadata. + */ + void translate(KunderaQuery query, EntityMetadata m) + { + String idColumn = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + for (Object obj : query.getFilterClauseQueue()) + { + boolean isIdColumn = false; + // parse for filter(e.g. where) clause. + + if (obj instanceof FilterClause) + { + String condition = ((FilterClause) obj).getCondition(); + String name = ((FilterClause) obj).getProperty(); + Object value = ((FilterClause) obj).getValue(); + if (idColumn.equalsIgnoreCase(name)) + { + isIdColumn = true; + } + onParseFilter(condition, name, value, isIdColumn, m); + } + else + { + // Case of AND and OR clause. + String opr = obj.toString(); + if (opr.equalsIgnoreCase("or")) + { + log.error("Support for OR clause is not enabled with in Hbase"); + throw new QueryHandlerException("Unsupported clause " + opr + " for Hbase"); + } + } + } + } + + /** + * Returns collection of parsed filter. + * + * @return map. + */ + Map getFilter() + { + if (filterList != null) + { + Map queryClause = new HashMap(); + queryClause.put(isIdColumn, new FilterList(filterList)); + return queryClause; + } + return null; + } + + /** + * On parsing filter clause(e.g. WHERE clause). + * + * @param condition + * condition + * @param name + * column name. + * @param value + * column value. + * @param isIdColumn + * if it is an id column. + * @param m + * entity metadata. + */ + private void onParseFilter(String condition, String name, Object value, boolean isIdColumn, EntityMetadata m) + { + CompareOp operator = HBaseUtils.getOperator(condition, isIdColumn); + byte[] valueInBytes = getBytes(name, m, value); + + if (!isIdColumn) + { + List columns = null; + if (new StringTokenizer(name, ".").countTokens() > 1) + { + columns = getTranslatedColumns(m, new String[] { name }, 0); + } + + if (columns != null && !columns.isEmpty()) + { + name = columns.get(0); + } + Filter f = new SingleColumnValueFilter(Bytes.toBytes(m.getTableName()), Bytes.toBytes(name), operator, + valueInBytes); + addToFilter(f); + } + else + { + if (operator.equals(CompareOp.GREATER_OR_EQUAL) || operator.equals(CompareOp.GREATER)) + { + startRow = valueInBytes; + } + else if (operator.equals(CompareOp.LESS_OR_EQUAL) || operator.equals(CompareOp.LESS)) + { + endRow = valueInBytes; + } + else if (operator.equals(CompareOp.EQUAL)) + { + rowKey = getBytes(m.getIdAttribute().getName(), m, value); + endRow = null; + isFindById = true; + } + } + this.isIdColumn = isIdColumn; + } + + /** + * @return the startRow + */ + byte[] getStartRow() + { + return startRow; + } + + /** + * @return the endRow + */ + byte[] getEndRow() + { + return endRow; + } + + /** + * @return the isFindById + */ + boolean isFindById() + { + return isFindById; + } + + boolean isRangeScan() + { + return startRow != null || endRow != null && !isFindById; + } + + /** + * @param f + */ + private void addToFilter(Filter f) + { + if (filterList == null) + { + filterList = new ArrayList(); + } + filterList.add(f); + } + } + + /** + * Returns bytes of value object. + * + * @param jpaFieldName + * @param m + * @param value + * @return + */ + private byte[] getBytes(String jpaFieldName, EntityMetadata m, Object value) + { + Attribute idCol = m.getIdAttribute(); + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entity = metaModel.entity(m.getEntityClazz()); + Class fieldClazz = null; + if (idCol.getName().equals(jpaFieldName)) + { + Field f = (Field) idCol.getJavaMember(); + fieldClazz = f.getType(); + } + else + { + StringTokenizer tokenizer = new StringTokenizer(jpaFieldName, "."); + String embeddedFieldName = null; + if (tokenizer.countTokens() > 1) + { + embeddedFieldName = tokenizer.nextToken(); + String fieldName = tokenizer.nextToken(); + Attribute embeddableAttribute = entity.getAttribute(embeddedFieldName); + EmbeddableType embeddableType = metaModel.embeddable(embeddableAttribute.getJavaType()); + Attribute embeddedAttribute = embeddableType.getAttribute(fieldName); + jpaFieldName = ((AbstractAttribute) embeddedAttribute).getJPAColumnName(); + fieldClazz = ((AbstractAttribute) embeddedAttribute).getBindableJavaType(); + } + else + { + String fieldName = m.getFieldName(jpaFieldName); + Attribute col = entity.getAttribute(fieldName); + fieldClazz = ((AbstractAttribute) col).getBindableJavaType(); + } + } + + if (fieldClazz != null) + { + return HBaseUtils.getBytes(value, fieldClazz); + } + else + { + log.error("Error while handling data type for {} .", jpaFieldName); + throw new QueryHandlerException("field type is null for:" + jpaFieldName); + } + } + + @Override + public void close() + { + // TODO Auto-generated method stub + + } + + @Override + public Iterator iterate() + { + EntityMetadata m = getEntityMetadata(); + Client client = persistenceDelegeator.getClient(m); + +// MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata()); + if (!MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + throw new UnsupportedOperationException("Scrolling over hbase is unsupported for lucene queries"); + } + QueryTranslator translator = new QueryTranslator(); + translator.translate(getKunderaQuery(), m); + // start with 1 as first element is alias. + List columns = getTranslatedColumns(m, getKunderaQuery().getResult(), 1); + + return new ResultIterator((HBaseClient) client, m, persistenceDelegeator, + getFetchSize() != null ? getFetchSize() : this.maxResult, translator, columns); + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/ResultIterator.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/ResultIterator.java new file mode 100644 index 000000000..052f9cf29 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/query/ResultIterator.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.query; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; + +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.FilterList; +import org.apache.hadoop.hbase.filter.KeyOnlyFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.admin.HBaseDataHandler; +import com.impetus.client.hbase.query.HBaseQuery.QueryTranslator; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.query.IResultIterator; +import com.impetus.kundera.query.QueryHandlerException; + +/** + * ResultIterator class, used to iterate over results. + * + * @author Vivek.Mishra + * + */ +class ResultIterator implements IResultIterator +{ + private HBaseClient client; + + private EntityMetadata entityMetadata; + + private PersistenceDelegator persistenceDelegator; + + private HBaseDataHandler handler; + + private QueryTranslator translator; + + private List columns; + + private int fetchSize; + + private int count; + + private boolean scrollComplete; + + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(ResultIterator.class); + + public ResultIterator(HBaseClient client, EntityMetadata m, PersistenceDelegator pd, int fetchSize, + QueryTranslator translator, List columns) + { + this.entityMetadata = m; + this.client = client; + this.persistenceDelegator = pd; + this.handler = ((HBaseClient) client).getHandle(); + this.handler.setFetchSize(fetchSize); + this.fetchSize = fetchSize; + this.translator = translator; + this.columns = columns; + onQuery(m, client); + } + + @Override + public boolean hasNext() + { + + boolean available = handler.hasNext(); + if (!available || fetchSize == 0) + { + scrollComplete = true; + handler.reset(); + return false; + } + return available; + } + + @Override + public E next() + { + if (!checkOnFetchSize() || scrollComplete) + { + throw new NoSuchElementException("Nothing to scroll further for:" + entityMetadata.getEntityClazz()); + } + + E result = (E) handler.next(entityMetadata); + if (!entityMetadata.isRelationViaJoinTable() + && (entityMetadata.getRelationNames() == null || (entityMetadata.getRelationNames().isEmpty()))) + { + return result; + } + else + { + return result = setRelationEntities(result, client, entityMetadata); + } + } + + @Override + public void remove() + { + throw new UnsupportedOperationException("remove() over result iterator is not supported"); + } + + private E setRelationEntities(Object enhanceEntity, Client client, EntityMetadata m) + { + // Enhance entities can contain or may not contain relation. + // if it contain a relation means it is a child + // if it does not then it means it is a parent. + E result = null; + if (enhanceEntity != null) + { + + if (!(enhanceEntity instanceof EnhanceEntity)) + { + enhanceEntity = new EnhanceEntity(enhanceEntity, PropertyAccessorHelper.getId(enhanceEntity, m), null); + } + + EnhanceEntity ee = (EnhanceEntity) enhanceEntity; + + result = (E) client.getReader().recursivelyFindEntities(ee.getEntity(), ee.getRelations(), m, + persistenceDelegator, false); + } + + return result; + } + + /** + * Parses and translates query into HBase filter and invokes client's method + * to return list of entities. + * + * @param m + * Entity metadata + * @param client + * hbase client + * @return list of entities. + */ + private void onQuery(EntityMetadata m, Client client) + { + + try + { + // Called only in case of standalone entity. + Map filter = translator.getFilter(); + String[] columnAsArr = getColumnsAsArray(); + + if (isFindKeyOnly(m, columnAsArr)) + { + this.handler.setFilter(new KeyOnlyFilter()); + } + + if (this.translator.isFindById() && (filter == null && columns == null)) + { + handler.readData(m.getTableName(), m.getEntityClazz(), entityMetadata, translator.rowKey, + m.getRelationNames(), null); + + } + if (translator.isFindById() && filter == null && columns != null) + { + handler.readDataByRange(m.getTableName(), m.getEntityClazz(), m, translator.rowKey, translator.rowKey, + columnAsArr, null); + } + if (MetadataUtils.useSecondryIndex(((ClientBase) client).getClientMetadata())) + { + if (filter == null && !translator.isFindById()) + { + // means complete scan without where clause, scan all + // records. + // findAll. + if (translator.isRangeScan()) + { + handler.readDataByRange(m.getTableName(), m.getEntityClazz(), m, translator.getStartRow(), + translator.getEndRow(), columnAsArr, null); + } + else + { + handler.readDataByRange(m.getTableName(), m.getEntityClazz(), m, null, null, columnAsArr, null); + } + } + else + { + // means WHERE clause is present. + + FilterList f = new FilterList(); + if (filter != null && filter.values() != null && !filter.values().isEmpty()) + { + f.addFilter(filter.values().iterator().next()); + } + if (translator.isRangeScan()) + { + handler.readDataByRange(m.getTableName(), m.getEntityClazz(), m, translator.getStartRow(), + translator.getEndRow(), columnAsArr, f); + } + else + { + // if range query. means query over id column. create + // range + // scan method. + + handler.readData(m.getTableName(), entityMetadata.getEntityClazz(), entityMetadata, null, + m.getRelationNames(), f, columnAsArr); + } + } + } + } + catch (IOException ioex) + { + log.error("Error while executing query{} , Caused by:", ioex); + throw new QueryHandlerException("Error while executing , Caused by:", ioex); + } + } + + private String[] getColumnsAsArray() + { + return columns.toArray(new String[columns.size()]); + } + + /** + * @param metadata + * @param columns + * @return + */ + private boolean isFindKeyOnly(EntityMetadata metadata, String[] columns) + { + int noOFColumnsToFind = 0; + boolean findIdOnly = false; + if (columns != null) + { + for (String column : columns) + { + if (column != null) + { + if (column.equals(((AbstractAttribute) metadata.getIdAttribute()).getJPAColumnName())) + { + noOFColumnsToFind++; + findIdOnly = true; + } + else + { + noOFColumnsToFind++; + findIdOnly = false; + } + } + } + } + if (noOFColumnsToFind == 1 && findIdOnly) + { + return true; + } + return false; + } + + @Override + public List next(int chunkSize) + { + throw new UnsupportedOperationException("Fetch in chunks is not yet supported over HBase!"); + } + + /** + * Check on fetch size. returns true, if count on fetched rows is less than + * fetch size. + * + * @return + */ + private boolean checkOnFetchSize() + { + if (count++ < fetchSize) + { + return true; + } + count = 0; + scrollComplete = true; + return false; + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/schemamanager/HBaseSchemaManager.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/schemamanager/HBaseSchemaManager.java new file mode 100644 index 000000000..9a09ed69a --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/schemamanager/HBaseSchemaManager.java @@ -0,0 +1,434 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemamanager; + +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.MasterNotRunningException; +import org.apache.hadoop.hbase.TableNotFoundException; +import org.apache.hadoop.hbase.ZooKeeperConnectionException; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.config.HBasePropertyReader; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema.Table; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.TableInfo; +import com.impetus.kundera.configure.schema.api.AbstractSchemaManager; +import com.impetus.kundera.configure.schema.api.SchemaManager; + +/** + * Manages auto schema operation {@code ScheamOperationType} for HBase data + * store. + * + * @author Kuldeep.kumar + * + */ +public class HBaseSchemaManager extends AbstractSchemaManager implements SchemaManager +{ + private static final String DEFAULT_ZOOKEEPER_PORT = "2181"; + + /** + * Hbase admin variable holds the admin authorities. + */ + private static HBaseAdmin admin; + + /** + * logger used for logging statement. + */ + private static final Logger logger = LoggerFactory.getLogger(HBaseSchemaManager.class); + + // private Properties schemaProperties; + + private List tables; + + /** + * Initialises HBase schema manager + * + * @param clientFactory + * client factory. + */ + public HBaseSchemaManager(String clientFactory, Map puProperties) + { + super(clientFactory, puProperties); + } + + @Override + /** + * Export schema handles the handleOperation method. + */ + public void exportSchema(final String persistenceUnit, List schemas) + { + super.exportSchema(persistenceUnit,schemas); + } + + /** + * update method update schema and table for the list of tableInfos + * + * @param tableInfos + * list of TableInfos. + */ + protected void update(List tableInfos) + { + for (TableInfo tableInfo : tableInfos) + { + if (tableInfo != null && tableInfo.getTableName() != null) + { + HTableDescriptor hTableDescriptor = getTableMetaData(tableInfo); + try + { + HTableDescriptor descriptor = admin.getTableDescriptor(tableInfo.getTableName().getBytes()); + if (descriptor.getNameAsString().equalsIgnoreCase(tableInfo.getTableName())) + { + if (admin.isTableEnabled(tableInfo.getTableName().getBytes())) + { + admin.disableTable(tableInfo.getTableName().getBytes()); + } + HColumnDescriptor[] descriptors = descriptor.getColumnFamilies(); + if (tableInfo.getColumnMetadatas() != null) + { + boolean found = false; + HColumnDescriptor columnDescriptor = new HColumnDescriptor(tableInfo.getTableName()); + for (HColumnDescriptor hColumnDescriptor : descriptors) + { + if (hColumnDescriptor.getNameAsString().equalsIgnoreCase(tableInfo.getTableName())) + { + found = true; + break; + } + } + if (!found) + { + admin.addColumn(tableInfo.getTableName(), columnDescriptor); + } + } + if (admin.isTableDisabled(tableInfo.getTableName().getBytes())) + { + admin.enableTable(tableInfo.getTableName().getBytes()); + } + } + } + catch (IOException e) + { + try + { + admin.createTable(hTableDescriptor); + } + catch (IOException ioe) + { + logger.error("Check for network connection, Caused by:", ioe); + throw new SchemaGenerationException(ioe, "Hbase"); + } + + } + } + } + } + + /** + * validate method validate schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void validate(List tableInfos) + { + for (TableInfo tableInfo : tableInfos) + { + HTableDescriptor hTableDescriptor; + try + { + hTableDescriptor = admin.getTableDescriptor(tableInfo.getTableName().getBytes()); + if (tableInfo.getColumnMetadatas() != null) + { + boolean isColumnFound = false; + for (HColumnDescriptor columnDescriptor : hTableDescriptor.getColumnFamilies()) + { + if (columnDescriptor.getNameAsString().equalsIgnoreCase(tableInfo.getTableName())) + { + isColumnFound = true; + break; + } + } + if (!isColumnFound) + { + throw new SchemaGenerationException("column " + tableInfo.getTableName() + + " does not exist in table " + tableInfo.getTableName() + "", "Hbase", + tableInfo.getTableName(), tableInfo.getTableName()); + } + } + } + catch (TableNotFoundException tnfex) + { + throw new SchemaGenerationException("table " + tableInfo.getTableName() + " does not exist ", tnfex, + "Hbase"); + } + catch (IOException ioe) + { + logger.error("Either check for network connection or table isn't in enabled state, Caused by:", ioe); + throw new SchemaGenerationException(ioe, "Hbase"); + } + } + } + + /** + * create_drop method creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create_drop(List tableInfos) + { + create(tableInfos); + } + + /** + * create method creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create(List tableInfos) + { + for (TableInfo tableInfo : tableInfos) + { + if (tableInfo != null && tableInfo.getTableName() != null) + { + try + { + if (admin.isTableAvailable(tableInfo.getTableName())) + { + if (admin.isTableEnabled(tableInfo.getTableName())) + { + admin.disableTable(tableInfo.getTableName()); + } + admin.deleteTable(tableInfo.getTableName()); + } + } + catch (TableNotFoundException e) + { + logger.info("creating table " + tableInfo.getTableName()); + } + catch (IOException ioex) + { + logger.error("Either table isn't in enabled state or some network problem, Caused by: ", ioex); + throw new SchemaGenerationException(ioex, "Hbase"); + } + HTableDescriptor hTableDescriptor = getTableMetaData(tableInfo); + try + { + admin.createTable(hTableDescriptor); + if (admin.isTableDisabled(tableInfo.getTableName())) + { + admin.enableTable(tableInfo.getTableName()); + } + } + catch (IOException ioe) + { + logger.error("Error while creating table, Caused by:", ioe); + throw new SchemaGenerationException(ioe, "Hbase"); + } + } + } + } + + /** + * drop schema method drop the table + */ + public void dropSchema() + { + if (operation != null && operation.equalsIgnoreCase("create-drop")) + { + for (TableInfo tableInfo : tableInfos) + { + if (tableInfo != null && tableInfo.getTableName() != null) + { + try + { + if (admin.isTableAvailable(tableInfo.getTableName())) + { + if (admin.isTableEnabled(tableInfo.getTableName())) + { + admin.disableTable(tableInfo.getTableName()); + } + admin.deleteTable(tableInfo.getTableName()); + } + } + catch (TableNotFoundException tnfe) + { + logger.error("Table doesn't exist, Caused by ", tnfe); + throw new SchemaGenerationException(tnfe, "Hbase"); + } + catch (IOException ioe) + { + logger.error("Table isn't in enabled state, Caused by", ioe); + throw new SchemaGenerationException(ioe, "Hbase"); + } + } + } + } + operation = null; + admin = null; + } + + /** + * initiate client method initiates the client. + * + * @return boolean value ie client started or not. + * + */ + protected boolean initiateClient() + { + String message = null; + for (String host : hosts) + { + vaildateHostPort(host, port); + + Configuration hadoopConf = new Configuration(); + hadoopConf.set("hbase.master", host + ":" + port); + conn = HBasePropertyReader.hsmd.getDataStore() != null ? HBasePropertyReader.hsmd.getDataStore() + .getConnection() : null; + if (conn != null && conn.getProperties() != null) + { + String zookeeperHost = conn.getProperties().getProperty("hbase.zookeeper.quorum"); + String zookeeperPort = conn.getProperties().getProperty("hbase.zookeeper.property.clientPort"); + vaildateHostPort(zookeeperHost, zookeeperPort); + hadoopConf.set("hbase.zookeeper.quorum", zookeeperHost != null ? zookeeperHost : host); + hadoopConf.set("hbase.zookeeper.property.clientPort", zookeeperPort != null ? zookeeperPort + : DEFAULT_ZOOKEEPER_PORT); + } + else + { + hadoopConf.set("hbase.zookeeper.quorum", host); + hadoopConf.set("hbase.zookeeper.property.clientPort", DEFAULT_ZOOKEEPER_PORT); + } + HBaseConfiguration conf = new HBaseConfiguration(hadoopConf); + try + { + admin = new HBaseAdmin(conf); + return true; + } + catch (MasterNotRunningException mnre) + { + message = mnre.getMessage(); + logger.error("Master not running exception, Caused by:", mnre); + } + catch (ZooKeeperConnectionException zkce) + { + message = zkce.getMessage(); + logger.error("Unable to connect to zookeeper, Caused by:", zkce); + } + } + throw new SchemaGenerationException("Master not running exception, Caused by:" + message); + } + + /** + * Validate host and port. + * + * @param host + * @param port + */ + private void vaildateHostPort(String host, String port) + { + if (host == null || !StringUtils.isNumeric(port) || port.isEmpty()) + { + logger.error("Host or port should not be null / port should be numeric"); + throw new IllegalArgumentException("Host or port should not be null / port should be numeric"); + } + } + + /** + * get Table metadata method returns the HTableDescriptor of table for given + * tableInfo + * + * @return HHTableDescriptor object for tableInfo + */ + private HTableDescriptor getTableMetaData(TableInfo tableInfo) + { + HTableDescriptor tableDescriptor = new HTableDescriptor(tableInfo.getTableName()); + Properties tableProperties = null; + schemas = HBasePropertyReader.hsmd.getDataStore() != null ? HBasePropertyReader.hsmd.getDataStore() + .getSchemas() : null; + if (schemas != null && !schemas.isEmpty()) + { + for (Schema s : schemas) + { + if (s.getName() != null && s.getName().equalsIgnoreCase(tableInfo.getTableName())) + { + tableProperties = s.getSchemaProperties(); + tables = s.getTables(); + } + } + } + if (tableInfo.getColumnMetadatas() != null) + { + HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(tableInfo.getTableName()); + setColumnFamilyProperties(hColumnDescriptor, tableInfo.getTableName()); + tableDescriptor.addFamily(hColumnDescriptor); + } + if (tableProperties != null) + { + for (Object o : tableProperties.keySet()) + { + tableDescriptor.setValue(Bytes.toBytes(o.toString()), Bytes.toBytes(tableProperties.get(o).toString())); + } + } + return tableDescriptor; + } + + private void setColumnFamilyProperties(HColumnDescriptor columnDescriptor, String tableName) + { + dataStore = HBasePropertyReader.hsmd.getDataStore(); + if (dataStore != null) + { + if (tables != null && !tables.isEmpty()) + { + for (Table t : tables) + { + Properties columnProperties = t.getProperties(); + if (t.getName() != null && t.getName().equalsIgnoreCase(columnDescriptor.getNameAsString()) + && columnProperties != null) + { + for (Object o : columnProperties.keySet()) + { + columnDescriptor.setValue(Bytes.toBytes(o.toString()), + Bytes.toBytes(columnProperties.get(o).toString())); + } + } + } + } + } + } + + @Override + public boolean validateEntity(Class clazz) + { + // TODO Auto-generated method stub + return true; + } + +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseReader.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseReader.java new file mode 100644 index 000000000..6977d0d04 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseReader.java @@ -0,0 +1,421 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.hadoop.hbase.KeyValue; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.util.Bytes; + +import com.impetus.client.hbase.HBaseData; +import com.impetus.client.hbase.Reader; +import com.impetus.client.hbase.utils.HBaseUtils; + +/** + * Implmentation class for HBase for Reader interface. + * + * @author vivek.mishra + */ +public class HBaseReader implements Reader +{ + private ResultScanner scanner = null; + + private Iterator resultsIter; + + private Integer fetchSize; + + private Integer counter = 0; + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Reader#LoadData(org.apache.hadoop.hbase.client + * .HTable, java.lang.String, java.lang.String) + */ +/* @Override + public List LoadData(HTableInterface hTable, String columnFamily, Object rowKey, Filter filter, + String... columns) throws IOException + { + List results = null; + if (scanner == null) + { + + // only in case of find by id + Scan scan = null; + if (rowKey != null) + { + byte[] rowKeyBytes = HBaseUtils.getBytes(rowKey); + Get g = new Get(rowKeyBytes); + scan = new Scan(g); + } + else + { + scan = new Scan(); + } + setScanCriteria(filter, columnFamily, null, scan, columns); + scanner = hTable.getScanner(scan); + resultsIter = scanner.iterator(); + } + return scanResults(columnFamily, results); + } +*/ + + @Override + public List LoadData(HTableInterface hTable, String columnFamily, Object rowKey, Filter filter, + String... columns) throws IOException + { + List results = new ArrayList(); + if (scanner == null) + { + + // only in case of find by id + Scan scan = null; + if (rowKey != null) + { + byte[] rowKeyBytes = HBaseUtils.getBytes(rowKey); + Get g = new Get(rowKeyBytes); + //TODO: After more than one column family for 1 table. this should work. currently failing for embeddable entities. +// if(columnFamily != null) +// { +// g.addFamily(Bytes.toBytes(columnFamily)); +// } + + if(filter != null) + { + g.setFilter(filter); + } + Result result = hTable.get(g); + + if (result != null && result.list() != null) + { + HBaseData data = null; + for (KeyValue value : result.list()) + { + data = new HBaseData(columnFamily != null ? columnFamily : new String(value.getFamily()), + value.getRow()); + break; + } + + if (data != null) + { + data.setColumns(result.list()); + results.add(data); + } + + } + return results; + + // scan = new Scan(g); + } + else + { + scan = new Scan(); + } + setScanCriteria(filter, columnFamily, null, scan, columns); + scanner = hTable.getScanner(scan); + resultsIter = scanner.iterator(); + } + return scanResults(columnFamily, results); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Reader#LoadData(org.apache.hadoop.hbase.client + * .HTable, java.lang.String) + */ + @Override + public List LoadData(HTableInterface hTable, Object rowKey, Filter filter, String... columns) + throws IOException + { + return LoadData(hTable, Bytes.toString(hTable.getTableName()), rowKey, filter, columns); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Reader#loadAll(org.apache.hadoop.hbase.client + * .HTable, org.apache.hadoop.hbase.filter.Filter, byte[], byte[]) + */ + @Override + public List loadAll(HTableInterface hTable, Filter filter, byte[] startRow, byte[] endRow, + String columnFamily, String qualifier, String[] columns) throws IOException + { + List results = null; + if (scanner == null) + { + Scan s = null; + if (startRow != null && endRow != null && startRow.equals(endRow)) + { + Get g = new Get(startRow); + s = new Scan(g); + } + else if (startRow != null && endRow != null) + { + s = new Scan(startRow, endRow); + } + else if (startRow != null) + { + s = new Scan(startRow); + } + else if (endRow != null) + { + s = new Scan(); + s.setStopRow(endRow); + } + else + { + s = new Scan(); + } + setScanCriteria(filter, columnFamily, qualifier, s, columns); + scanner = hTable.getScanner(s); + resultsIter = scanner.iterator(); + } + return scanResults(null, results); + } + + /** + * @param filter + * @param columnFamily + * @param s + */ + private void setScanCriteria(Filter filter, String columnFamily, String qualifier, Scan s, String[] columns) + { + if (filter != null) + { + s.setFilter(filter); + } + if (columnFamily != null && qualifier != null) + { + s.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier)); + } + else if (columnFamily != null) + { + // s.addFamily(Bytes.toBytes(columnFamily)); + } + + if (columns != null && columns.length > 0) + { + for (String columnName : columns) + { + if (columnFamily != null && columnName != null) + { + s.addColumn(Bytes.toBytes(columnFamily), Bytes.toBytes(columnName)); + } + } + } + } + + /** + * Scan and populate {@link HBaseData} collection using scanned results. + * + * @param columnFamily + * column family. + * @param results + * results. + * @param scanner + * result scanner. + * @return collection of scanned results. + * @throws IOException + */ + private List scanResults(final String columnFamily, List results) throws IOException + { + HBaseData data = null; + + if (fetchSize == null) + { + for (Result result : scanner) + { + List values = result.list(); + for (KeyValue value : values) + { + data = new HBaseData(columnFamily != null ? columnFamily : new String(value.getFamily()), + value.getRow()); + break; + } + data.setColumns(values); + if (results == null) + { + results = new ArrayList(); + } + results.add(data); + } + + scanner = null; + resultsIter = null; + } + return results; + } + + @Override + public Object[] scanRowKeys(final HTableInterface hTable, final Filter filter, final String columnFamilyName, + final String columnName, final Class rowKeyClazz) throws IOException + { + List rowKeys = new ArrayList(); + + if (scanner == null) + { + Scan s = new Scan(); + s.setFilter(filter); + s.addColumn(Bytes.toBytes(columnFamilyName), Bytes.toBytes(columnName)); + scanner = hTable.getScanner(s); + resultsIter = scanner.iterator(); + } + + if (fetchSize == null) + { + for (Result result : scanner) + { + for (KeyValue keyValue : result.list()) + { + rowKeys.add(HBaseUtils.fromBytes(keyValue.getRow(), rowKeyClazz)); + } + } + } + if (rowKeys != null && !rowKeys.isEmpty()) + { + return rowKeys.toArray(new Object[0]); + } + return null; + } + + public List loadAll(final HTableInterface hTable, final List rows, final String columnFamily, + final String[] columns) throws IOException + { + List results = null; + + HBaseData data = null; + + List getRequest = new ArrayList(); + for (Object rowKey : rows) + { + if (rowKey != null) + { + byte[] rowKeyBytes = HBaseUtils.getBytes(rowKey); + Get request = new Get(rowKeyBytes); + getRequest.add(request); + } + } + Result[] rawResult = hTable.get(getRequest); + + for (Result result : rawResult) + { + List values = result.list(); + + if (values != null) + { + for (KeyValue value : values) + { + data = new HBaseData(columnFamily != null ? columnFamily : new String(value.getFamily()), + value.getRow()); + break; + } + + data.setColumns(values); + if (results == null) + { + results = new ArrayList(); + } + results.add(data); + } + } + return results; + } + + public void setFetchSize(final int fetchSize) + { + this.fetchSize = fetchSize; + } + + /** + * + * @return next element of HbaseData. + */ + public HBaseData next() + { + HBaseData data = null; + Result result = resultsIter.next(); + List values = result.list(); + for (KeyValue value : values) + { + data = new HBaseData(new String(value.getFamily()), value.getRow()); + break; + } + data.setColumns(values); + return data; + } + + // public List next(final int chunkSize) + // { + // List results = new ArrayList(); + // for (int i = 1; i <= chunkSize; i++) + // { + // HBaseData data = next(); + // if (data == null) + // { + // counter++; + // resultsIter = null; + // break; + // } + // results.add(data); + // } + // return results; + // } + + public boolean hasNext() + { + if (scanner == null) + { + return false; + } + else + { + if (fetchSize != null) + { + if (counter < fetchSize) + { + counter++; + return resultsIter.hasNext(); + } + } + else + { + return resultsIter.hasNext(); + } + } + return false; + } + + public void reset() + { + scanner = null; + fetchSize = null; + resultsIter = null; + counter = 0; + } +} diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseWriter.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseWriter.java new file mode 100644 index 000000000..fbf947033 --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/service/HBaseWriter.java @@ -0,0 +1,360 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.service; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hbase.client.Delete; +import org.apache.hadoop.hbase.client.Get; +import org.apache.hadoop.hbase.client.HTableInterface; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.Writer; +import com.impetus.client.hbase.admin.HBaseDataHandler.HBaseDataWrapper; +import com.impetus.client.hbase.utils.HBaseUtils; +import com.impetus.kundera.Constants; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.metadata.MetadataUtils; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; + +/** + * The Class HBaseWriter responsible for all sort of get and put commands to be + * executed on a hTable. + * + * @author vivek.mishra + */ +public class HBaseWriter implements Writer +{ + /** the log used by this class. */ + private static Logger log = LoggerFactory.getLogger(HBaseWriter.class); + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeColumns(org.apache.hadoop.hbase. + * client.HTable, java.lang.String, java.lang.Object, java.util.Set, + * java.lang.Object) + */ + @Override + public void writeColumns(HTableInterface htable, String columnFamily, Object rowKey, Set columns, + + Object columnFamilyObj) throws IOException + { + Put p = preparePut(columnFamily, rowKey, columns, columnFamilyObj); + htable.put(p); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeColumn(org.apache.hadoop.hbase.client + * .HTable, java.lang.String, java.lang.Object, + * javax.persistence.metamodel.Attribute, java.lang.Object) + */ + @Override + public void writeColumn(HTableInterface htable, String columnFamily, Object rowKey, Attribute column, + Object columnObj) throws IOException + { + Put p = new Put(HBaseUtils.getBytes(rowKey)); + p.add(Bytes.toBytes(columnFamily), Bytes.toBytes(((AbstractAttribute) column).getJPAColumnName()), + Bytes.toBytes(columnObj.toString())); + + htable.put(p); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeColumns(org.apache.hadoop.hbase. + * client.HTable, java.lang.Object, java.util.Set, java.lang.Object) + */ + @Override + public void writeColumns(HTableInterface htable, Object rowKey, Set columns, Object entity) + throws IOException + { + Put p = new Put(HBaseUtils.getBytes(rowKey)); + + boolean present = false; + for (Attribute column : columns) + { + if (!column.isCollection() && !((SingularAttribute) column).isId()) + { + String qualifier = ((AbstractAttribute) column).getJPAColumnName(); + try + { + byte[] qualValInBytes = Bytes.toBytes(qualifier); + Object value = PropertyAccessorHelper.getObject(entity, (Field) column.getJavaMember()); + if (value != null) + { + p.add(htable.getTableName(), qualValInBytes, System.currentTimeMillis(), + HBaseUtils.getBytes(value)); + present = true; + } + } + catch (PropertyAccessException e1) + { + throw new IOException(e1); + } + } + } + if (present) + { + htable.put(p); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeColumns(org.apache.hadoop.hbase. + * client.HTable, java.lang.Object, java.util.Map) + */ + @Override + public void writeColumns(HTableInterface htable, Object rowKey, Map columns) throws IOException + { + + Put p = new Put(HBaseUtils.getBytes(rowKey)); + + boolean isPresent = false; + for (String columnName : columns.keySet()) + { + p.add(htable.getTableName(), Bytes.toBytes(columnName), HBaseUtils.getBytes(columns.get(columnName))); + isPresent = true; + // /* .getBytes() */); + } + + if (isPresent) + { + htable.put(p); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeRelations(org.apache.hadoop.hbase + * .client.HTable, java.lang.Object, boolean, java.util.List) + */ + @Override + public void writeRelations(HTableInterface htable, Object rowKey, boolean containsEmbeddedObjectsOnly, + List relations) throws IOException + { + Put p = new Put(HBaseUtils.getBytes(rowKey)); + + boolean isPresent = false; + for (RelationHolder r : relations) + { + if (r != null) + { + if (containsEmbeddedObjectsOnly) + { + p.add(Bytes.toBytes(r.getRelationName()), Bytes.toBytes(r.getRelationName()), + PropertyAccessorHelper.getBytes(r.getRelationValue())); + isPresent = true; + } + else + { + p.add(htable.getTableName(), Bytes.toBytes(r.getRelationName()), System.currentTimeMillis(), + PropertyAccessorHelper.getBytes(r.getRelationValue())); + // p.add(Bytes.toBytes(r.getRelationName()), + // System.currentTimeMillis(), + // Bytes.toBytes(r.getRelationValue())); + isPresent = true; + } + + } + } + + if (isPresent) + { + htable.put(p); + } + } + + // TODO: Scope of performance improvement in this code + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#writeForeignKeys(org.apache.hadoop.hbase + * .client.HTable, java.lang.String, java.util.Map) + */ + @Override + public void writeForeignKeys(HTableInterface hTable, String rowKey, Map> foreignKeyMap) + throws IOException + { + Put p = new Put(Bytes.toBytes(rowKey)); + + // Checking if foreign key column family exists + Get g = new Get(Bytes.toBytes(rowKey)); + Result r = hTable.get(g); + + boolean isPresent = false; + + for (Map.Entry> entry : foreignKeyMap.entrySet()) + { + String property = entry.getKey(); // Foreign key name + Set foreignKeys = entry.getValue(); + String keys = MetadataUtils.serializeKeys(foreignKeys); + + // Check if there was any existing foreign key value, if yes, append + // it + byte[] value = r.getValue(Bytes.toBytes(Constants.FOREIGN_KEY_EMBEDDED_COLUMN_NAME), + Bytes.toBytes(property)); + String existingForeignKey = Bytes.toString(value); + + if (existingForeignKey == null || existingForeignKey.isEmpty()) + { + p.add(Bytes.toBytes(Constants.FOREIGN_KEY_EMBEDDED_COLUMN_NAME), Bytes.toBytes(property), + Bytes.toBytes(keys)); + isPresent = true; + } + else + { + p.add(Bytes.toBytes(Constants.FOREIGN_KEY_EMBEDDED_COLUMN_NAME), Bytes.toBytes(property), + Bytes.toBytes(existingForeignKey + Constants.FOREIGN_KEY_SEPARATOR + keys)); + isPresent = true; + } + + } + + if (isPresent) + { + hTable.put(p); + } + } + + /** + * Support for delete over HBase. + * + * @param hTable + * the h table + * @param rowKey + * the row key + * @param columnFamily + * the column family + */ + /* + * (non-Javadoc) + * + * @see + * com.impetus.client.hbase.Writer#delete(org.apache.hadoop.hbase.client + * .HTable, java.lang.String, java.lang.String) + */ + public void delete(HTableInterface hTable, Object rowKey, String columnFamily) + { + try + { + byte[] rowBytes = HBaseUtils.getBytes(rowKey); + Delete delete = new Delete(rowBytes); + + hTable.delete(delete); + } + catch (IOException e) + { + log.error("Error while delete on hbase for : " + rowKey); + throw new PersistenceException(e); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.client.hbase.Writer#persistRows(java.util.Map) + */ + @Override + public void persistRows(Map> rows) throws IOException + { + List dataSet = new ArrayList(rows.size()); + for (HTableInterface hTable : rows.keySet()) + { + List row = rows.get(hTable); + for (HBaseDataWrapper data : row) + { + dataSet.add(preparePut(data.getColumnFamily(), data.getRowKey(), data.getColumns(), data.getEntity())); + } + hTable.put(dataSet); + dataSet.clear(); + } + + } + + /** + * Prepare put. + * + * @param columnFamily + * the column family + * @param rowKey + * the row key + * @param columns + * the columns + * @param columnFamilyObj + * the column family obj + * @return the put + * @throws IOException + * Signals that an I/O exception has occurred. + */ + private Put preparePut(String columnFamily, Object rowKey, Set columns, Object columnFamilyObj) + throws IOException + { + Put p = new Put(HBaseUtils.getBytes(rowKey)); + for (Attribute column : columns) + // for (Column column : columns) + { + if (!column.isCollection() && !((SingularAttribute) column).isId()) + { + String qualifier = ((AbstractAttribute) column).getJPAColumnName(); + try + { + Object o = PropertyAccessorHelper.getObject(columnFamilyObj, (Field) column.getJavaMember()); + byte[] value = HBaseUtils.getBytes(o); + if (value != null && columnFamily != null) + { + p.add(Bytes.toBytes(columnFamily), Bytes.toBytes(qualifier), value); + } + } + catch (PropertyAccessException e1) + { + throw new IOException(e1); + } + } + } + return p; + } + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/main/java/com/impetus/client/hbase/utils/HBaseUtils.java b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/utils/HBaseUtils.java new file mode 100644 index 000000000..6d9d2789d --- /dev/null +++ b/src/kundera-hbase/src/main/java/com/impetus/client/hbase/utils/HBaseUtils.java @@ -0,0 +1,185 @@ +package com.impetus.client.hbase.utils; + +import java.math.BigDecimal; + +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.util.Bytes; + +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.property.PropertyAccessorFactory; + +public final class HBaseUtils +{ + /** + * @param value + * @param clazz + * @return + */ + public static byte[] getBytes(Object value, Class clazz) + { + if (/* isId || */clazz.isAssignableFrom(String.class)) + { + return Bytes.toBytes(value.toString()); + } + else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) + { + return Bytes.toBytes(value instanceof Integer ? (Integer) value : new Integer(value.toString())); + } + else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) + { + return Bytes.toBytes(value instanceof Long ? (Long) value : new Long(value.toString())); + } + else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) + { + return Bytes.toBytes(value instanceof Boolean ? (Boolean) value : new Boolean(value.toString())); + } + else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) + { + return Bytes.toBytes(value instanceof Double ? (Double) value : new Double(value.toString())); + } + // else if (clazz.isAssignableFrom(java.util.UUID.class)) + // { + // return Bytes.toBytes(value.toString()); + // } + else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) + { + return Bytes.toBytes(value instanceof Float ? (Float) value : new Float(value.toString())); + } + else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) + { + return Bytes.toBytes(value instanceof Short ? (Short) value : new Short(value.toString())); + } + else if (clazz.equals(BigDecimal.class)) + { + return Bytes.toBytes(value instanceof BigDecimal ? (BigDecimal) value : new BigDecimal(value.toString())); + } + else + { + if (value.getClass().isAssignableFrom(String.class)) + { + value = PropertyAccessorFactory.getPropertyAccessor(clazz).fromString(clazz, value.toString()); + } + return PropertyAccessorFactory.getPropertyAccessor(clazz).toBytes(value); + } + } + + /** + * Returns bytes value for given value. + * + * @param fieldName + * field name. + * @param m + * entity metadata + * @param value + * value. + * @return bytes value. + */ + public static byte[] getBytes(Object o) + { + if (o != null) + { + return getBytes(o, o.getClass()); + } + + return null; + } + + public static Object fromBytes(EntityMetadata m, byte[] b) + { + Class idFieldClass = m.getIdAttribute().getJavaType(); + return fromBytes(b, idFieldClass); + } + + public static Object fromBytes(byte[] b, Class clazz) + { + + if (clazz.isAssignableFrom(String.class)) + { + return Bytes.toString(b); + } + else if (clazz.equals(int.class) || clazz.isAssignableFrom(Integer.class)) + { + return Bytes.toInt(b); + } + else if (clazz.equals(long.class) || clazz.isAssignableFrom(Long.class)) + { + return Bytes.toLong(b); + } + else if (clazz.equals(boolean.class) || clazz.isAssignableFrom(Boolean.class)) + { + return Bytes.toBoolean(b); + } + else if (clazz.equals(double.class) || clazz.isAssignableFrom(Double.class)) + { + return Bytes.toDouble(b); + } + // else if (clazz.isAssignableFrom(java.util.UUID.class)) + // { + // return Bytes.toBytes(b.toString()); + // } + else if (clazz.equals(float.class) || clazz.isAssignableFrom(Float.class)) + { + return Bytes.toFloat(b); + } + else if (clazz.equals(short.class) || clazz.isAssignableFrom(Short.class)) + { + return Bytes.toShort(b); + } + else if (clazz.equals(BigDecimal.class)) + { + return Bytes.toBigDecimal(b); + } + else + { + return PropertyAccessorFactory.getPropertyAccessor(clazz).fromBytes(clazz, b); + } + } + + /** + * Gets the operator. + * + * @param condition + * the condition + * @param idPresent + * the id present + * @return the operator + */ + public static CompareOp getOperator(String condition, boolean idPresent) + { + if (/* !idPresent && */condition.equals("=")) + { + return CompareOp.EQUAL; + } + else if (/* !idPresent && */condition.equals(">")) + { + return CompareOp.GREATER; + } + else if (/* !idPresent && */condition.equals("<")) + { + return CompareOp.LESS; + } + else if (condition.equals(">=")) + { + return CompareOp.GREATER_OR_EQUAL; + } + else if (condition.equals("<=")) + { + return CompareOp.LESS_OR_EQUAL; + } + else + { + if (!idPresent) + { + throw new UnsupportedOperationException(" Condition " + condition + " is not suported in hbase!"); + } + else + { + throw new UnsupportedOperationException(" Condition " + condition + + " is not suported for query on row key!"); + + } + } + + } + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/BookInfo.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/BookInfo.java new file mode 100644 index 000000000..641ebff76 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/BookInfo.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.book.recommendation.hbase.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * + * @author Kuldeep.Mishra + * + */ +@Entity +@Table(name = "bookinfo", schema = "KunderaExamples@hbaseTest") +public class BookInfo +{ + @Id + @Column(name = "bookId") + private String bookId; + + @Column(name = "md5") + private String md5; + + @Column(name = "title") + private String title; + + @Column(name = "author") + private String author; + + @Column(name = "yearofpub") + private String yearofpub; + + @Column(name = "publisher") + private String publisher; + + @Column(name = "imageurls") + private String imageurls; + + @Column(name = "imageurlm") + private String imageurlm; + + @Column(name = "imageurll") + private String imageurll; + + @Column(name = "price") + private Float price; + + public String getBookId() + { + return bookId; + } + + public void setBookId(String bookId) + { + this.bookId = bookId; + } + + public String getMd5() + { + return md5; + } + + public void setMd5(String md5) + { + this.md5 = md5; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getAuthor() + { + return author; + } + + public void setAuthor(String author) + { + this.author = author; + } + + public String getYearofpub() + { + return yearofpub; + } + + public void setYearofpub(String yearofpub) + { + this.yearofpub = yearofpub; + } + + public String getPublisher() + { + return publisher; + } + + public void setPublisher(String publisher) + { + this.publisher = publisher; + } + + public String getImageurls() + { + return imageurls; + } + + public void setImageurls(String imageurls) + { + this.imageurls = imageurls; + } + + public String getImageurlm() + { + return imageurlm; + } + + public void setImageurlm(String imageurlm) + { + this.imageurlm = imageurlm; + } + + public String getImageurll() + { + return imageurll; + } + + public void setImageurll(String imageurll) + { + this.imageurll = imageurll; + } + + public Float getPrice() + { + return price; + } + + public void setPrice(Float price) + { + this.price = price; + } +} diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarity.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarity.java new file mode 100644 index 000000000..7bfd854ad --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarity.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.book.recommendation.hbase.model; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * + * @author Kuldeep.Mishra + * + */ +@Entity +@Table(name = "city_similarity", schema = "KunderaExamples@hbaseTest") +public class CitySimilarity +{ + + @Id + @Column(name = "id") + private String id; + + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "bookId") + private BookInfo bookInfo; + +// priva + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setBookInfo(BookInfo bookInfo) + { + this.bookInfo = bookInfo; + } + + public BookInfo getBookInfo() + { + return bookInfo; + } +} diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarityTest.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarityTest.java new file mode 100644 index 000000000..5b0cddc89 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/CitySimilarityTest.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.book.recommendation.hbase.model; + +import java.util.Iterator; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.KeyOnlyFilter; +import org.apache.hadoop.hbase.filter.PrefixFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.client.Client; + +/** + * + * @author Kuldeep.Mishra + * + */ +public class CitySimilarityTest +{ + + private EntityManagerFactory emf; + + private EntityManager em; + + private HBaseCli cli = new HBaseCli(); + + @Before + public void setUp() throws Exception + { + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + em = emf.createEntityManager(); + BookInfo info1 = new BookInfo(); + info1.setBookId("book1"); + info1.setAuthor("Vivek"); + + BookInfo info2 = new BookInfo(); + info2.setBookId("book2"); + info2.setAuthor("Amresh"); + + CitySimilarity city1 = new CitySimilarity(); + city1.setId("100_1"); + city1.setBookInfo(info1); + + CitySimilarity city2 = new CitySimilarity(); + city2.setId("100_2"); + city2.setBookInfo(info2); + + em.persist(city1); + em.persist(city2); + + em.flush(); + em.clear(); + } + + @After + public void tearDown() throws Exception + { + em.remove(em.find(CitySimilarity.class, "100_1")); + em.remove(em.find(CitySimilarity.class, "100_2")); + em.close(); + emf.close(); + cli.stopCluster(null); + } + + @Test + public void testIterator() + { + String query2 = "select u from CitySimilarity u"; + com.impetus.kundera.query.Query queryObject = (com.impetus.kundera.query.Query) em + .createQuery(query2); + + queryObject.setFetchSize(10); + + Iterator resultIterator = queryObject.iterate(); + CitySimilarity cityS = null; + int counter = 0; + while (resultIterator.hasNext()) + { + counter++; + cityS = resultIterator.next(); + Assert.assertNotNull(cityS); + Assert.assertNotNull(cityS.getId()); + Assert.assertNotNull(cityS.getBookInfo()); + Assert.assertNotNull(cityS.getBookInfo().getBookId()); + } + Assert.assertEquals(2, counter); + } + + @Test + public void testIteratorWithOneFilter() + { + Map clients = (Map) em.getDelegate(); + + HBaseClient client = (HBaseClient) clients.get("hbaseTest"); + + Filter filter = new PrefixFilter(Bytes.toBytes("100" + "_")); + + client.setFilter(new KeyOnlyFilter()); + client.addFilter("city_similarity", filter); + + String query2 = "select u from CitySimilarity u"; + com.impetus.kundera.query.Query queryObject = (com.impetus.kundera.query.Query) em + .createQuery(query2); + + queryObject.setFetchSize(10); + + Iterator resultIterator = queryObject.iterate(); + CitySimilarity cityS = null; + int counter = 0; + while (resultIterator.hasNext()) + { + counter++; + cityS = resultIterator.next(); + Assert.assertNotNull(cityS); + Assert.assertNotNull(cityS.getId()); + Assert.assertNull(cityS.getBookInfo()); + } + Assert.assertEquals(2, counter); + } + + @Test + public void testIteratorWithTwoFilter() + { + Map clients = (Map) em.getDelegate(); + + HBaseClient client = (HBaseClient) clients.get("hbaseTest"); + + Filter filter = new PrefixFilter(Bytes.toBytes("100" + "_")); + + client.addFilter("city_similarity", filter); + client.addFilter("bookinfo", new KeyOnlyFilter()); + + String query2 = "select u from CitySimilarity u"; + com.impetus.kundera.query.Query queryObject = (com.impetus.kundera.query.Query) em + .createQuery(query2); + + queryObject.setFetchSize(10); + + Iterator resultIterator = queryObject.iterate(); + CitySimilarity cityS = null; + int counter = 0; + while (resultIterator.hasNext()) + { + counter++; + cityS = resultIterator.next(); + Assert.assertNotNull(cityS); + Assert.assertNotNull(cityS.getBookInfo()); + Assert.assertNotNull(cityS.getBookInfo().getBookId()); + Assert.assertNull(cityS.getBookInfo().getTitle()); + Assert.assertNull(cityS.getBookInfo().getAuthor()); + Assert.assertNull(cityS.getBookInfo().getImageurll()); + Assert.assertNull(cityS.getBookInfo().getImageurlm()); + Assert.assertNull(cityS.getBookInfo().getImageurls()); + Assert.assertNull(cityS.getBookInfo().getMd5()); + Assert.assertNull(cityS.getBookInfo().getPublisher()); + Assert.assertNull(cityS.getBookInfo().getYearofpub()); + } + Assert.assertEquals(2, counter); + } +} diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPassword.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPassword.java new file mode 100644 index 000000000..8566fe8a4 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPassword.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.book.recommendation.hbase.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "userandpassword", schema = "KunderaExamples@hbaseTest") +public class UserAndPassword +{ + public static final String CF = "userandpassword"; + + public static final String CQ_USER_NAME = "username"; + + @Id + @Column(name = "id") + private String id; + + @Column(name = "username") + private String userName; + + @Column(name = "firstName") + private String firstName; + + @Column(name = "lastName") + private String lastName; + + @Column(name = "password") + private String password; + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserName() + { + return userName; + } + + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + public String getFirstName() + { + return firstName; + } + + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public String getLastName() + { + return lastName; + } +} diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPasswordTest.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPasswordTest.java new file mode 100644 index 000000000..b22614620 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserAndPasswordTest.java @@ -0,0 +1,198 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.book.recommendation.hbase.model; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.KeyOnlyFilter; +import org.apache.hadoop.hbase.filter.PrefixFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.client.Client; + +/** + * @author Kuldeep.Mishra + * + */ +public class UserAndPasswordTest +{ + + private EntityManagerFactory emf; + + private EntityManager em; + + private HBaseCli cli = new HBaseCli(); + + @Before + public void setUp() throws Exception + { + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + em = emf.createEntityManager(); + for (int i = 1; i < 10; i++) + { + UserAndPassword user = new UserAndPassword(); + user.setId(i + ""); + user.setUserName("KK" + i); + user.setFirstName("Kuldeep" + i); + user.setLastName("Mishra" + i); + user.setPassword("xxx" + i); + em.persist(user); + } + em.clear(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (int i = 1; i < 10; i++) + { + em.remove(em.find(UserAndPassword.class, i + "")); + } + em.close(); + emf.close(); + cli.stopCluster(null); + } + + @Test + public void testWithSameEM() + { + try + { + String query = "select u from UserAndPassword u where u.userName=KK5"; + com.impetus.kundera.query.Query q = (com.impetus.kundera.query.Query) em + .createQuery(query); + q.setFetchSize(1); + Iterator results = q.iterate(); + while (results.hasNext()) + { + UserAndPassword user = results.next(); + Assert.assertNotNull(user); + Assert.assertEquals("KK5", user.getUserName()); + Assert.assertEquals("Kuldeep5", user.getFirstName()); + Assert.assertEquals("Mishra5", user.getLastName()); + Assert.assertEquals("xxx5", user.getPassword()); + Assert.assertEquals("5", user.getId()); + } + + query = "select u from UserAndPassword u where u.userName=KK6"; + q = (com.impetus.kundera.query.Query) em.createQuery(query); + q.setFetchSize(1); + results = q.iterate(); + while (results.hasNext()) + { + UserAndPassword user = results.next(); + Assert.assertNotNull(user); + Assert.assertEquals("KK6", user.getUserName()); + Assert.assertEquals("Kuldeep6", user.getFirstName()); + Assert.assertEquals("Mishra6", user.getLastName()); + Assert.assertEquals("xxx6", user.getPassword()); + Assert.assertEquals("6", user.getId()); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } + + @Test + public void testWithDifferentEM() + { + try + { + String query = "select u from UserAndPassword u where u.userName=KK5"; + com.impetus.kundera.query.Query q = (com.impetus.kundera.query.Query) em + .createQuery(query); + q.setFetchSize(1); + Iterator results = q.iterate(); + while (results.hasNext()) + { + UserAndPassword user = results.next(); + Assert.assertNotNull(user); + Assert.assertEquals("KK5", user.getUserName()); + Assert.assertEquals("Kuldeep5", user.getFirstName()); + Assert.assertEquals("Mishra5", user.getLastName()); + Assert.assertEquals("xxx5", user.getPassword()); + Assert.assertEquals("5", user.getId()); + } + + // query = "select u from UserAndPassword u"; + // q = (com.impetus.kundera.query.Query) + // em.createQuery(query); + // + // Map clients = (Map) + // em.getDelegate(); + // HBaseClient client = (HBaseClient) clients.get("hbaseTest"); + // + // Filter filter = new PrefixFilter(Bytes.toBytes("KK")); + // + // client.setFilter(new KeyOnlyFilter()); + // client.addFilter("city_similarity", filter); + // + // q.setFetchSize(4); + // results = q.iterate(); + // while (results.hasNext()) + // { + // List users = + // ((com.impetus.client.hbase.query.ResultIterator) + // results) + // .next(2); + // Assert.assertNotNull(users); + // Assert.assertEquals(2, users.size()); + // } + // em.close(); + + em = emf.createEntityManager(); + query = "select u from UserAndPassword u where u.userName=KK6"; + q = (com.impetus.kundera.query.Query) em.createQuery(query); + q.setFetchSize(1); + results = q.iterate(); + while (results.hasNext()) + { + UserAndPassword user = results.next(); + Assert.assertNotNull(user); + Assert.assertEquals("KK6", user.getUserName()); + Assert.assertEquals("Kuldeep6", user.getFirstName()); + Assert.assertEquals("Mishra6", user.getLastName()); + Assert.assertEquals("xxx6", user.getPassword()); + Assert.assertEquals("6", user.getId()); + } + } + catch (Exception ex) + { + ex.printStackTrace(); + Assert.fail(ex.getMessage()); + } + } +} diff --git a/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserInfo.java b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserInfo.java new file mode 100644 index 000000000..69aec6aab --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/book/recommendation/hbase/model/UserInfo.java @@ -0,0 +1,130 @@ +package com.book.recommendation.hbase.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "user_info", schema = "KunderaExamples@hbaseTest") +public class UserInfo +{ + @Id + @Column(name = "userId") + private String userId; + + @Column(name = "age") + private String age; + + @Column(name = "cityName") + private String cityName; + + @Column(name = "cityId") + private String cityId; + + @Column(name = "state") + private String state; + + @Column(name = "country") + private String country; + + @Column(name = "firstName") + private String firstName; + + @Column(name = "lastName") + private String lastName; + + @Column(name = "md5") + private String md5; + + public String getAge() + { + return age; + } + + public void setAge(String age) + { + this.age = age; + } + + public String getCityName() + { + return cityName; + } + + public void setCityName(String cityName) + { + this.cityName = cityName; + } + + public String getCityId() + { + return cityId; + } + + public void setCityId(String cityId) + { + this.cityId = cityId; + } + + public String getState() + { + return state; + } + + public void setState(String state) + { + this.state = state; + } + + public String getCountry() + { + return country; + } + + public void setCountry(String country) + { + this.country = country; + } + + public String getFirstName() + { + return firstName; + } + + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + public String getLastName() + { + return lastName; + } + + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public String getMd5() + { + return md5; + } + + public void setMd5(String md5) + { + this.md5 = md5; + } + + public void setUserId(String userId) + { + this.userId = userId; + } + + public String getUserId() + { + return userId; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseEntity.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseEntity.java new file mode 100644 index 000000000..dd216abb1 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseEntity.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.config; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseEntity", schema = "KunderaHbase@UsePropertyInHbase") +public class HBaseEntity +{ + + @Id + private String id; + + @Column(name = "NAME") + private String name; + + @Column(name = "AGE") + private short age; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUser.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUser.java new file mode 100644 index 000000000..13bdbb7af --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUser.java @@ -0,0 +1,80 @@ +/** + * + */ +package com.impetus.client.hbase.config; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "HBASEUSERXYZ", schema = "KunderaHbaseXmlTest@XmlPropertyTest") +public class HBaseUser +{ + + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUserTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUserTest.java new file mode 100644 index 000000000..471c597ac --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/config/HBaseUserTest.java @@ -0,0 +1,129 @@ +/** + * + */ +package com.impetus.client.hbase.config; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.TableNotFoundException; +import org.apache.hadoop.hbase.io.hfile.Compression.Algorithm; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.junits.HBaseCli; + +/** + * @author Kuldeep Mishra + * + */ +public class HBaseUserTest +{ + + private EntityManagerFactory emf; + + private HBaseCli cli; + + /** + * logger used for logging statement. + */ + private static final Logger logger = LoggerFactory.getLogger(HBaseUserTest.class); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + @Test + public void test() throws IOException + { + emf = Persistence.createEntityManagerFactory("XmlPropertyTest"); + try + { + HTableDescriptor hTableDescriptor = HBaseCli.utility.getHBaseAdmin().getTableDescriptor( + "HBASEUSERXYZ".getBytes()); + int count = 0; + for (HColumnDescriptor columnDescriptor : hTableDescriptor.getColumnFamilies()) + { + if (columnDescriptor.getNameAsString().equalsIgnoreCase("HBASEUSERXYZ")) + { + Assert.assertEquals(Algorithm.valueOf("GZ"), columnDescriptor.getCompactionCompressionType()); + Assert.assertEquals(Integer.parseInt("12345678"), columnDescriptor.getTimeToLive()); + Assert.assertEquals(Algorithm.valueOf("GZ"), columnDescriptor.getCompressionType()); + Assert.assertEquals(Integer.parseInt("6"), columnDescriptor.getMaxVersions()); + Assert.assertEquals(Integer.parseInt("3"), columnDescriptor.getMinVersions()); + count++; + } + } + Assert.assertEquals(1, count); + } + catch (TableNotFoundException tnfe) + { + logger.error("Error during UserTest, caused by :" + tnfe); + } + catch (IOException ie) + { + logger.error("Error during UserTest, caused by :" + ie); + } + finally + { + emf.close(); + Assert.assertTrue(HBaseCli.utility.getHBaseAdmin().isTableAvailable("HBASEUSERXYZ")); + cli.dropTable("HBASEUSERXYZ"); + } + } + + @Test + public void testUsingExternalProperty() throws IOException + { + Map puProperties = new HashMap(); + puProperties.put("kundera.ddl.auto.prepare", "create-drop"); + puProperties.put("kundera.keyspace", "KunderaHbaseKeyspace"); + emf = Persistence.createEntityManagerFactory("XmlPropertyTest", puProperties); + try + { + Assert.assertTrue(HBaseCli.utility.getHBaseAdmin().isTableAvailable("HBASEUSERXYZ")); + } + catch (TableNotFoundException tnfe) + { + logger.error("Error during UserTest, caused by :" + tnfe); + } + catch (IOException ie) + { + logger.error("Error during UserTest, caused by :" + ie); + } + finally + { + emf.close(); + if (HBaseCli.utility.getHBaseAdmin().isTableAvailable("HBASEUSERXYZ")) + { + cli.dropTable("HBASEUSERXYZ"); + } + } + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/BaseTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/BaseTest.java new file mode 100644 index 000000000..bcf820943 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/BaseTest.java @@ -0,0 +1,298 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import com.impetus.client.hbase.crud.PersonHBase.Day; + +/** + * The Class BaseTest. + * + * @author vivek.mishra + */ +public abstract class BaseTest +{ + /** + * Prepare hbase instance. + * + * @param rowKey + * the row key + * @param age + * the age + * @return the person h base + */ + protected PersonHBase prepareHbaseInstance(String rowKey, int age) + { + PersonHBase o = new PersonHBase(); + o.setPersonId(rowKey); + o.setPersonName("vivek"); + o.setAge(age); + o.setDay(Day.MONDAY); + o.setMonth(Month.MARCH); + return o; + } + + /** + * Find by id. + * + * @param + * the element type + * @param clazz + * the clazz + * @param rowKey + * the row key + * @param em + * the em + * @return the e + */ + protected E findById(Class clazz, Object rowKey, EntityManager em) + { + return em.find(clazz, rowKey); + } + + /** + * Assert find by name. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param fieldName + * the field name + */ + protected void assertFindByName(EntityManager em, String clazz, E e, String name, + String fieldName) + { + + String query = "Select p from " + clazz + " p where p." + fieldName + " = " + name; + // // find by name. + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert find by name and age. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAge(EntityManager em, String clazz, E e, String name, + String minVal, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find by name and age gt and lt. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeGTAndLT(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // // find by name, age clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal + " and p.age < " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(1, results.size()); + } + + /** + * Assert find by name and age between. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeBetween(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // find by between clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + + " and p.age between " + minVal + " and " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + + } + + /** + * Assert find by range. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByRange(EntityManager em, String clazz, E e, String minVal, + String maxVal, String fieldName) + + { + // find by Range. + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " Between " + minVal + " and " + + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find without where clause. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + */ + protected void assertFindWithoutWhereClause(EntityManager em, String clazz, E e) + { + // find by without where clause. + Query q = em.createQuery("Select p from " + clazz + " p"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert on merge. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param oldName + * the old name + * @param newName + * the new name + * @param fieldName + * the field name + */ + protected void assertOnMerge(EntityManager em, String clazz, E e, String oldName, + String newName, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + oldName); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + newName); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertNotSame(oldName, getPersonName(e, results.get(0))); + Assert.assertEquals(newName, getPersonName(e, results.get(0))); + } + + /** + * Gets the person name. + * + * @param + * the element type + * @param e + * the e + * @param result + * the result + * @return the person name + */ + private String getPersonName(E e, Object result) + { + throw new RuntimeException("Support for " + e + "is not yet supported"); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseBatchProcessorTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseBatchProcessorTest.java new file mode 100644 index 000000000..437de42cf --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseBatchProcessorTest.java @@ -0,0 +1,160 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.persistence.api.Batcher; + +/** + * Batch processing test case for cassandra. + * + * @author vivek.mishra + * + */ +public class HBaseBatchProcessorTest +{ + + /** + * persistence unit. + */ + private static final String PERSISTENCE_UNIT = "HbaseBatchTest"; + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + /** Rows. */ + private List rows; + + private HBaseCli cli; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + em = emf.createEntityManager(); + } + + /** + * Test case for batch operation. + */ + @Test + public void onBatch() + { + int counter = 0; + rows = prepareData(10); + for (PersonBatchHBaseEntity entity : rows) + { + em.persist(entity); + + // check for implicit flush. + if (++counter == 5) + { + Map clients = (Map) em.getDelegate(); + + Batcher client = (Batcher) clients.get(PERSISTENCE_UNIT); + Assert.assertEquals(5, client.getBatchSize()); + em.clear(); + for (int i = 0; i < 5; i++) + { + + // assert on each batch size record + Assert.assertNotNull(em.find(PersonBatchHBaseEntity.class, rows.get(i).getPersonId())); + + // as batch size is 5. + Assert.assertNull(em.find(PersonBatchHBaseEntity.class, rows.get(6).getPersonId())); + } + // means implicit flush must happen + } + } + + // flush all on close. + // explicit flush on close + em.clear(); + em.flush(); + + String sql = " Select p from PersonBatchHBaseEntity p"; + Query query = em.createQuery(sql); + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(10, results.size()); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (PersonBatchHBaseEntity o : rows) + { + em.remove(o); + } + + em.close(); + emf.close(); + + if (cli != null ) + { + cli.dropTable("PERSON_BATCH"); + cli.stopCluster("PERSON_BATCH"); + } + + } + + /** + * @param noOfRecords + * @return + */ + private List prepareData(Integer noOfRecords) + { + List persons = new ArrayList(); + for (int i = 1; i <= noOfRecords; i++) + { + PersonBatchHBaseEntity o = new PersonBatchHBaseEntity(); + o.setPersonId(i + ""); + o.setPersonName("vivek" + i); + o.setAge(10); + persons.add(o); + } + + return persons; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseIdQueryTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseIdQueryTest.java new file mode 100644 index 000000000..32d2dbbef --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HBaseIdQueryTest.java @@ -0,0 +1,482 @@ +/** + * + */ +package com.impetus.client.hbase.crud; + +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.utils.LuceneCleanupUtilities; + +/** + * @author Kuldeep Mishra + * + */ +public class HBaseIdQueryTest extends BaseTest +{ + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private Map col; + + private HBaseCli cli; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (Object val : col.values()) + { + em.remove(val); + } + em.close(); + emf.close(); + if (cli != null) + { + cli.dropTable("NETSTAT_DTL_SMRY"); + cli.dropTable("STUDENT"); + cli.dropTable("PERSON_HBASE"); + cli.dropTable("PERSON"); + cli.dropTable("Address"); + cli.stopCluster("PERSON_HBASE"); + } + LuceneCleanupUtilities.cleanLuceneDirectory("hbaseTest"); + } + + @Test + public void test() + { + init(); + em.clear(); + findById(); + findByWithOutWhereClause(); + findByIdEQ(); + findByIdLT(); + findByIdLTE(); + findByIdGT(); + findByIdGTE(); + findByIdGTEAndLT(); + findByIdGTAndLTE(); + findByIdAndAge(); + findByIdGTAndAgeGTAndLT(); + findByIdAndAgeGTAndLT(); + findByIdGTEAndAge(); + findByIdLTEAndAge(); + } + + /** + * + */ + private void findByIdAndAge() + { + String qry = "Select p.personName, p.age from PersonHBase p where p.personId = 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonHBase person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + Assert.assertEquals(10, person.getAge().intValue()); + } + } + + /** + * + */ + private void findByIdAndAgeGTAndLT() + {/* + * String qry = + * "Select p.personName from PersonHBase p where p.personId = 1 and p.personName = vivek and p.age >=10 and p.age <= 20" + * ; Query q = em.createQuery(qry); List persons = + * q.getResultList(); Assert.assertNotNull(persons); Assert.assertEquals(1, + * persons.size()); int count = 0; for (PersonHBase person : persons) { if + * (person.getPersonId().equals("1")) { Assert.assertNull(person.getAge()); + * Assert.assertEquals("vivek", person.getPersonName()); count++; } } + * Assert.assertEquals(1, count); + */ + } + + /** + * + */ + private void findByWithOutWhereClause() + { + String qry = "Select p.personName from PersonHBase p"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + + } + + /** + * + */ + private void findByIdEQ() + { + String qry = "Select p.personName from PersonHBase p where p.personId = 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonHBase person : persons) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("2", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + + } + + /** + * + */ + private void findByIdLT() + { + String qry = "Select p.personName from PersonHBase p where p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findByIdLTE() + { + String qry = "Select p.personName, p.age from PersonHBase p where p.personId <= 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertEquals(new Integer(20), person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findByIdGT() + { + String qry = "Select p.personName from PersonHBase p where p.personId > 1"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTE() + { + String qry = "Select p.personName from PersonHBase p where p.personId >= 1 "; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTEAndLT() + { + String qry = "Select p.personName from PersonHBase p where p.personId >= 1 and p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + + } + + /** + * + */ + private void findByIdGTAndLTE() + { + String qry = "Select p.personName from PersonHBase p where p.personId > 1 and p.personId <= 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + Assert.assertEquals("1", person.getPersonId()); + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + Assert.assertEquals(1, count); + } + + /** + * + */ + private void findByIdGTAndAgeGTAndLT() + { + + String qry = "Select p.personName from PersonHBase p where p.personId > 1 and p.age >=10 and p.age <= 20"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonHBase person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findById() + { + PersonHBase personHBase = findById(PersonHBase.class, "1", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(10), personHBase.getAge()); + + personHBase = findById(PersonHBase.class, "2", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(20), personHBase.getAge()); + + personHBase = findById(PersonHBase.class, "3", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(15), personHBase.getAge()); + } + + /** + * + */ + private void findByIdGTEAndAge() + { + String qry = "Select p.personName, p.age from PersonHBase p where p.personId >= 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonHBase person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + } + + /** + * + */ + private void findByIdLTEAndAge() + { + String qry = "Select p.personName, p.age from PersonHBase p where p.personId <= 3 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonHBase person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + + } + + private void init() + { + + // cli.createTable("PERSON"); + // cli.addColumnFamily("PERSON", "PERSON"); + Object p1 = prepareHbaseInstance("1", 10); + Object p2 = prepareHbaseInstance("2", 20); + Object p3 = prepareHbaseInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Human.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Human.java new file mode 100644 index 000000000..fb8c2c3fc --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Human.java @@ -0,0 +1,62 @@ +package com.impetus.client.hbase.crud; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "Humans", schema = "KunderaExamples@ilpMainSchema") +public class Human +{ + @Id + public String hId; + + @Column(name = "humanAlive") + public Boolean humanAlive; + + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "humanId") + // @Column(name = "HumansPrivatePhoto") + public HumansPrivatePhoto humansPrivatePhoto; + + public Human() + { + + } + + public Human(String humanId) + { + this.hId = humanId; + } + + public Boolean getHumanAlive() + { + return humanAlive; + } + + public void setHumanAlive(Boolean humanAlive) + { + this.humanAlive = humanAlive; + } + + public HumansPrivatePhoto getHumansPrivatePhoto() + { + return humansPrivatePhoto; + } + + public void setHumansPrivatePhoto(HumansPrivatePhoto humansPrivatePhoto) + { + this.humansPrivatePhoto = humansPrivatePhoto; + } + + public String getHumanId() + { + return hId; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumanTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumanTest.java new file mode 100644 index 000000000..d08485d8a --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumanTest.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; + +public class HumanTest +{ + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private HBaseCli cli; + + @Before + public void setUp() + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("ilpMainSchema"); + em = emf.createEntityManager(); + + } + + @Test + public void testOps() + { + String humanId = "human1"; + Human human = new Human(humanId); + human.setHumanAlive(true); + HumansPrivatePhoto photo = new HumansPrivatePhoto(humanId); + photo.setPhotoName("myPhoto"); + human.setHumansPrivatePhoto(photo); + photo.setHuman(human); + em.persist(human); + + em.clear(); // just to clear pc cache + + Human result = em.find(Human.class, humanId); + Assert.assertNotNull(result); + Assert.assertEquals(humanId, result.getHumanId()); + Assert.assertEquals("myPhoto", result.getHumansPrivatePhoto().getPhotoName()); + Assert.assertTrue(result.getHumanAlive()); + + } + + @After + public void tearDown() + { + em.close(); + emf.close(); + if (cli != null) + { + cli.dropTable("Humans"); + cli.dropTable("HumansPrivatePhoto"); + } + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumansPrivatePhoto.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumansPrivatePhoto.java new file mode 100644 index 000000000..62fd67491 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/HumansPrivatePhoto.java @@ -0,0 +1,58 @@ +package com.impetus.client.hbase.crud; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +@Entity +@Table(name = "HumansPrivatePhoto", schema = "KunderaExamples@ilpMainSchema") +public class HumansPrivatePhoto +{ + + @Id + public String humanId; + + @OneToOne(mappedBy = "humansPrivatePhoto", cascade = CascadeType.REFRESH) + // @PrimaryKeyJoinColumn + public Human human; + + public String photoName; + + public HumansPrivatePhoto() + { + + } + + public HumansPrivatePhoto(String humanId) + { + this.humanId = humanId; + } + + public Human getHuman() + { + return human; + } + + public void setHuman(Human human) + { + this.human = human; + } + + public String getPhotoName() + { + return photoName; + } + + public void setPhotoName(String photoName) + { + this.photoName = photoName; + } + + public String getHumanId() + { + return humanId; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Month.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Month.java new file mode 100644 index 000000000..5dcec868d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/Month.java @@ -0,0 +1,6 @@ +package com.impetus.client.hbase.crud; + +enum Month +{ + JAN, FEB, MARCH, APRIL, MAY, JUNE; +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonBatchHBaseEntity.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonBatchHBaseEntity.java new file mode 100644 index 000000000..d03e4a107 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonBatchHBaseEntity.java @@ -0,0 +1,124 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON_BATCH", schema = "KunderaMongoDataType@HbaseBatchTest") +// @Index(index = true, columns = { "PERSON_NAME", "AGE" }) +public class PersonBatchHBaseEntity +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBase.java new file mode 100644 index 000000000..8d4b7aa47 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBase.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Table; + +// TODO: Auto-generated Javadoc +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON_HBASE", schema = "KunderaExamples@hbaseTest") +public class PersonHBase +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "ENUM") + @Enumerated(EnumType.STRING) + private Day day; + + @Column(name = "MONTH_ENUM") + @Enumerated(EnumType.STRING) + private Month month; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the day + */ + public Day getDay() + { + return day; + } + + /** + * @param day + * the day to set + */ + public void setDay(Day day) + { + this.day = day; + } + + public Month getMonth() + { + return month; + } + + public void setMonth(Month month) + { + this.month = month; + } + + enum Day + { + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBaseTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBaseTest.java new file mode 100644 index 000000000..516dd0766 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/PersonHBaseTest.java @@ -0,0 +1,242 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; +import org.apache.hadoop.hbase.filter.Filter; +import org.apache.hadoop.hbase.filter.QualifierFilter; +import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.crud.PersonHBase.Day; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.utils.LuceneCleanupUtilities; + +public class PersonHBaseTest extends BaseTest +{ + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private Map col; + + private HBaseCli cli; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + @Test + public void onInsertHbase() throws Exception + { + Query findQuery = em.createQuery("Select p from PersonHBase p"); + List allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p from PersonHBase p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p.age from PersonHBase p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + init(); + em.clear(); + PersonHBase personHBase = findById(PersonHBase.class, "1", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(Day.MONDAY, personHBase.getDay()); + Assert.assertEquals(Month.MARCH, personHBase.getMonth()); + + assertFindByName(em, "PersonHBase", PersonHBase.class, "vivek", "personName"); + assertFindByNameAndAge(em, "PersonHBase", PersonHBase.class, "vivek", "10", "personName"); + assertFindByNameAndAgeGTAndLT(em, "PersonHBase", PersonHBase.class, "vivek", "10", "20", "personName"); + assertFindByNameAndAgeBetween(em, "PersonHBase", PersonHBase.class, "vivek", "10", "15", "personName"); + assertFindByRange(em, "PersonHBase", PersonHBase.class, "1", "3", "personId"); + assertFindWithoutWhereClause(em, "PersonHBase", PersonHBase.class); + selectIdQuery(); + } + + private void selectIdQuery() + { + String query = "select p.personId from PersonHBase p"; + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + + + query = "select p from PersonHBase p"; + com.impetus.kundera.query.Query queryObject = (com.impetus.kundera.query.Query) em.createQuery(query); + queryObject.setFetchSize(1); + + Iterator resultIterator = queryObject.iterate(); + PersonHBase person =null; + int counter = 0; + while(resultIterator.hasNext()) + { + counter++; + person = resultIterator.next(); + Assert.assertNotNull(person.getPersonId()); + Assert.assertNotNull(person.getPersonName()); + } + + Assert.assertEquals(1, counter); + + + query = "Select p.personId from PersonHBase p where p.personName = vivek"; + // // find by name. + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + + q = em.createQuery("Select p.personId from PersonHBase p where p.personName = vivek and p.age > " + 10); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + Assert.assertNull(results.get(0).getAge()); + } + + private void init() + { + cli.startCluster(); + // cli.createTable("PERSON"); + // cli.addColumnFamily("PERSON", "PERSON"); + Object p1 = prepareHbaseInstance("1", 10); + Object p2 = prepareHbaseInstance("2", 20); + Object p3 = prepareHbaseInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + } + + @Test + public void onFilterOperation() + { + init(); + + Map clients = (Map) em.getDelegate(); + Client client = clients.get("hbaseTest"); + + Filter f = new QualifierFilter(); + f = new SingleColumnValueFilter("PERSON_NAME".getBytes(), "PERSON_NAME".getBytes(), CompareOp.EQUAL, + "vivek".getBytes()); + + ((HBaseClient) client).setFilter(f); + + em.clear(); + // find by without where clause. + Query q = em.createQuery("Select p from " + PersonHBase.class.getSimpleName() + " p"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + // @Test + // public void onMergeHbase() { + // em.persist(prepareHbaseInstance("1", 10)); + // PersonHBase personHBase = findById(PersonHBase.class, "1", em); + // Assert.assertNotNull(personHBase); + // Assert.assertEquals("vivek", personHBase.getPersonName()); + // personHBase.setPersonName("Newvivek"); + // + // em.merge(personHBase); + // assertOnMerge(em, "PersonHBase", PersonHBase.class); + // o.add(PersonHBase.class); + // } + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + + /* + * * Delete is working, but as row keys are not deleted from cassandra, + * so resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); + * em.remove(em.find(Person.class, "2")); + * em.remove(em.find(Person.class, "3")); em.close(); emf.close(); em = + * null; emf = null; + */ + for (Object val : col.values()) + { + em.remove(val); + } + em.close(); + emf.close(); + if (cli != null ) + { + cli.dropTable("NETSTAT_DTL_SMRY"); + cli.dropTable("STUDENT"); + cli.dropTable("PERSON_HBASE"); + cli.dropTable("PERSON"); + cli.dropTable("Address"); + cli.stopCluster("PERSON_HBASE"); + } + LuceneCleanupUtilities.cleanLuceneDirectory("hbaseTest"); + // if (cli.isStarted) + + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/AddressOTOHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/AddressOTOHbase.java new file mode 100644 index 000000000..c1a3c36e6 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/AddressOTOHbase.java @@ -0,0 +1,45 @@ +package com.impetus.client.hbase.crud.association; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "Address", schema = "KunderaExamples@hbaseTest") +public class AddressOTOHbase +{ + + @Id + @Column(name = "ADDRESS_ID") + private Double addressId; + + public AddressOTOHbase() + { + + } + + public AddressOTOHbase(Double addressId) + { + this.addressId = addressId; + } + + @Column(name = "address") + private String address; + + public String getAddress() + { + return address; + } + + public void setAddress(String address) + { + this.address = address; + } + + public Double getAddressId() + { + return addressId; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/HbaseAssociationTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/HbaseAssociationTest.java new file mode 100644 index 000000000..db814df79 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/HbaseAssociationTest.java @@ -0,0 +1,94 @@ +package com.impetus.client.hbase.crud.association; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.client.twitter.entities.PersonalDetailHbase; + +public class HbaseAssociationTest +{ + + private static final String ROW_KEY = "1"; + + /** The Constant REDIS_PU. */ + private static final String HBASE_PU = "hbaseTest"; + + /** The emf. */ + private EntityManagerFactory emf; + + private HBaseCli cli; + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(HbaseAssociationTest.class); + + @Before + public void setUp() + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory(HBASE_PU); + } + + @Test + public void testCrud() + { + EntityManager em = emf.createEntityManager(); + + PersonOTOHbase person = new PersonOTOHbase(ROW_KEY); + person.setAge(32); + person.setPersonName("vivek"); + AddressOTOHbase address = new AddressOTOHbase(12.23); + address.setAddress("india"); + person.setAddress(address); + + PersonalDetailHbase detail = new PersonalDetailHbase(); + detail.setName("KK"); + detail.setPassword("xxxxxxx"); + detail.setPersonalDetailId("xyz"); + detail.setRelationshipStatus("single"); + + person.setPersonalDetail(detail); + + em.persist(person); + + em.clear(); + PersonOTOHbase p = em.find(PersonOTOHbase.class, ROW_KEY); + + // Assertions. + Assert.assertNotNull(p); + Assert.assertEquals(person.getPersonId(), p.getPersonId()); + Assert.assertNotNull(p.getAddress()); + Assert.assertEquals(person.getAddress().getAddress(), p.getAddress().getAddress()); + Assert.assertNotNull(p.getPersonalDetail()); + Assert.assertNotNull(p.getPersonalDetail().getName()); + Assert.assertNotNull(p.getPersonalDetail().getPassword()); + Assert.assertNotNull(p.getPersonalDetail().getPersonalDetailId()); + Assert.assertNotNull(p.getPersonalDetail().getRelationshipStatus()); + + // Remove + em.remove(p); + + em.clear(); // clear cache + Assert.assertNull(em.find(AddressOTOHbase.class, 12.23)); + } + + @After + public void tearDown() + { + cli.dropTable("NETSTAT_DTL_SMRY"); + cli.dropTable("STUDENT"); + cli.dropTable("PERSON_HBASE"); + cli.dropTable("PERSON"); + cli.dropTable("Address"); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/PersonOTOHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/PersonOTOHbase.java new file mode 100644 index 000000000..c119a313e --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/association/PersonOTOHbase.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud.association; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import com.impetus.client.twitter.entities.PersonalDetailHbase; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON", schema = "KunderaExamples@hbaseTest") +public class PersonOTOHbase +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Embedded + private PersonalDetailHbase personalDetail; + + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "ADDRESS_ID") + private AddressOTOHbase address; + + public PersonOTOHbase(String personId) + { + this.personId = personId; + } + + public PersonOTOHbase() + { + + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + public AddressOTOHbase getAddress() + { + return address; + } + + public void setAddress(AddressOTOHbase address) + { + this.address = address; + } + + public void setAge(Integer age) + { + this.age = age; + } + + /** + * @return the personalDetail + */ + public PersonalDetailHbase getPersonalDetail() + { + return personalDetail; + } + + /** + * @param personalDetail + * the personalDetail to set + */ + public void setPersonalDetail(PersonalDetailHbase personalDetail) + { + this.personalDetail = personalDetail; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/Base.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/Base.java new file mode 100644 index 000000000..1ca7d6822 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/Base.java @@ -0,0 +1,47 @@ +package com.impetus.client.hbase.crud.datatypes; + +import com.impetus.kundera.datatypes.datagenerator.DataGenerator; +import com.impetus.kundera.datatypes.datagenerator.DataGeneratorFactory; + +public abstract class Base +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + DataGenerator dataGenerator; + + DataGeneratorFactory factory = new DataGeneratorFactory(); + + protected Object getMaxValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.maxValue(); + } + + protected Object getMinValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.minValue(); + } + + protected Object getRandomValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.randomValue(); + } + + protected Object getPartialValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.partialValue(); + } + + protected abstract void startCluster(); + + protected abstract void stopCluster(); + + protected abstract void createSchema(); + + protected abstract void dropSchema(); +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentBase.java new file mode 100644 index 000000000..a20e9ada2 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentBase.java @@ -0,0 +1,361 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud.datatypes; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.MasterNotRunningException; +import org.apache.hadoop.hbase.ZooKeeperConnectionException; + +import com.impetus.client.hbase.crud.BaseTest; + +/** + * The Class StudentBase. + * + * @param + * the element type + */ +public abstract class StudentBase extends BaseTest +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + /** The emf. */ + protected EntityManagerFactory emf; + + /** The em. */ + protected EntityManager em; + + // protected String persistenceUnit = + // /*"twissandra,twibase,twingo,picmysql"*/null; + + /** The student id1. */ + protected Object studentId1; + + /** The student id2. */ + protected Object studentId2; + + /** The student id3. */ + protected Object studentId3; + + /** The enrolment date. */ + protected Date enrolmentDate = new Date(); + + /** The joining date and time. */ + protected Date joiningDateAndTime = new Date(); + + /** The date. */ + protected long date = new Date().getTime(); + + /** The new sql date. */ + protected java.sql.Date newSqlDate = new java.sql.Date(date); + + /** The enrolment time. */ + protected Date enrolmentTime = new Date(); + + /** The sql time. */ + protected java.sql.Time sqlTime = new java.sql.Time(date); + + /** The sql timestamp. */ + protected java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(date); + + /** The big decimal. */ + protected BigDecimal bigDecimal = new BigDecimal(123456789); + + /** The big integer. */ + protected BigInteger bigInteger = new BigInteger("123456789"); + + /** The number of students. */ + protected int numberOfStudents = 1000; + + /** The calendar. */ + protected Calendar calendar = Calendar.getInstance(); + + /** The dao. */ + // StudentDao dao; + + /** + * Sets the up internal. + * + * @param persisntenceUnit + * the new up internal + * @throws InterruptedException + */ + protected void setupInternal(String persisntenceUnit) throws InterruptedException + { + // dao = new StudentDao(persistenceUnit); + + if (RUN_IN_EMBEDDED_MODE) + { + // if (!HBaseCli.isStarted) + startServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + + studentId1 = new Long(12345677); + studentId2 = new Long(12345678); + studentId3 = new Long(12345679); + + emf = Persistence.createEntityManagerFactory(persisntenceUnit); + em = emf.createEntityManager(); + } + + /** + * Sets the up internal. + * + * @param persistenceUnit + * the new up internal + * @throws InterruptedException + * @throws IOException + * @throws ZooKeeperConnectionException + * @throws MasterNotRunningException + */ + protected void teardownInternal(String persistenceUnit) throws InterruptedException, MasterNotRunningException, + ZooKeeperConnectionException, IOException + { + if (AUTO_MANAGE_SCHEMA) + { + deleteSchema(); + } + if (em != null) + { + em.close(); + } + if (emf != null) + { + emf.close(); + } + if (RUN_IN_EMBEDDED_MODE) + { + // if (HBaseCli.isStarted) + stopServer(); + } + } + + /** + * on insert. + * + * @param instance + * the instance + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + */ + protected void onInsert(E instance) throws InstantiationException, IllegalAccessException + { + + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", false, 10, 'A', (byte) 5, (short) 8, + (float) 61.6, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId2, 78575785898L, "Amresh", true, 20, 'B', (byte) 50, (short) 8, + (float) 63.6, 163.76765655, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId3, 78575785899L, "Amresh", true, 15, 'C', (byte) 50, (short) 8, + (float) 69.6, 163.76765656, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + ((E) instance.getClass().newInstance()))); + + } + + /** + * Prepare data. + * + * @param studentId + * the student id + * @param uniqueId + * the unique id + * @param studentName + * the student name + * @param isExceptional + * the is exceptional + * @param age + * the age + * @param semester + * the semester + * @param digitalSignature + * the digital signature + * @param cgpa + * the cgpa + * @param percentage + * the percentage + * @param height + * the height + * @param enrolmentDate + * the enrolment date + * @param enrolmentTime + * the enrolment time + * @param joiningDateAndTime + * the joining date and time + * @param yearsSpent + * the years spent + * @param rollNumber + * the roll number + * @param monthlyFee + * the monthly fee + * @param newSqlDate + * the new sql date + * @param sqlTime + * the sql time + * @param sqlTimestamp + * the sql timestamp + * @param bigDecimal + * the big decimal + * @param bigInteger + * the big integer + * @param calendar + * the calendar + * @param o + * the o + * @return the person + */ + protected E prepareData(long studentId, long uniqueId, String studentName, boolean isExceptional, int age, + char semester, byte digitalSignature, short cgpa, float percentage, double height, + java.util.Date enrolmentDate, java.util.Date enrolmentTime, java.util.Date joiningDateAndTime, + Integer yearsSpent, Long rollNumber, Double monthlyFee, java.sql.Date newSqlDate, java.sql.Time sqlTime, + java.sql.Timestamp sqlTimestamp, BigDecimal bigDecimal, BigInteger bigInteger, Calendar calendar, E o) + { + o.setStudentId((Long) studentId); + o.setUniqueId(uniqueId); + o.setStudentName(studentName); + o.setExceptional(isExceptional); + o.setAge(age); + o.setSemester(semester); + o.setDigitalSignature(digitalSignature); + o.setCgpa(cgpa); + o.setPercentage(percentage); + o.setHeight(height); + + o.setEnrolmentDate(enrolmentDate); + o.setEnrolmentTime(enrolmentTime); + o.setJoiningDateAndTime(joiningDateAndTime); + + o.setYearsSpent(yearsSpent); + o.setRollNumber(rollNumber); + o.setMonthlyFee(monthlyFee); + o.setSqlDate(newSqlDate); + o.setSqlTime(sqlTime); + o.setSqlTimestamp(sqlTimestamp); + o.setBigDecimal(bigDecimal); + o.setBigInteger(bigInteger); + o.setCalendar(calendar); + return (E) o; + } + + /** + * Assert on data types. + * + * @param s + * the s + */ + protected void assertOnDataTypes(E s) + { + + Assert.assertNotNull(s); + Assert.assertEquals(((Long) studentId1).longValue(), s.getStudentId()); + Assert.assertEquals(78575785897L, s.getUniqueId()); + Assert.assertEquals("Amresh", s.getStudentName()); + Assert.assertEquals(false, s.isExceptional()); + Assert.assertEquals(10, s.getAge()); + Assert.assertEquals('A', s.getSemester()); + Assert.assertEquals((byte) 5, s.getDigitalSignature()); + Assert.assertEquals((short) 8, s.getCgpa()); + Assert.assertEquals((float) 61.6, s.getPercentage()); + Assert.assertEquals(163.76765654, s.getHeight()); + + Assert.assertEquals(enrolmentDate.getDate(), s.getEnrolmentDate().getDate()); + Assert.assertEquals(enrolmentDate.getMonth(), s.getEnrolmentDate().getMonth()); + Assert.assertEquals(enrolmentDate.getYear(), s.getEnrolmentDate().getYear()); + + Assert.assertEquals(enrolmentTime.getHours(), s.getEnrolmentTime().getHours()); + Assert.assertEquals(enrolmentTime.getMinutes(), s.getEnrolmentTime().getMinutes()); + Assert.assertEquals(enrolmentTime.getSeconds(), s.getEnrolmentTime().getSeconds()); + + Assert.assertEquals(joiningDateAndTime.getDate(), s.getJoiningDateAndTime().getDate()); + Assert.assertEquals(joiningDateAndTime.getMonth(), s.getJoiningDateAndTime().getMonth()); + Assert.assertEquals(joiningDateAndTime.getYear(), s.getJoiningDateAndTime().getYear()); + Assert.assertEquals(joiningDateAndTime.getHours(), s.getJoiningDateAndTime().getHours()); + Assert.assertEquals(joiningDateAndTime.getMinutes(), s.getJoiningDateAndTime().getMinutes()); + Assert.assertEquals(joiningDateAndTime.getSeconds(), s.getJoiningDateAndTime().getSeconds()); + + Assert.assertEquals(newSqlDate.getDate(), s.getSqlDate().getDate()); + Assert.assertEquals(newSqlDate.getMonth(), s.getSqlDate().getMonth()); + Assert.assertEquals(newSqlDate.getYear(), s.getSqlDate().getYear()); + + Assert.assertEquals(sqlTime.getMinutes(), s.getSqlTime().getMinutes()); + Assert.assertEquals(sqlTime.getSeconds(), s.getSqlTime().getSeconds()); + Assert.assertEquals(sqlTime.getHours(), s.getSqlTime().getHours()); + + Assert.assertEquals(sqlTimestamp.getDate(), s.getSqlTimestamp().getDate()); + Assert.assertEquals(sqlTimestamp.getMonth(), s.getSqlTimestamp().getMonth()); + Assert.assertEquals(sqlTimestamp.getYear(), s.getSqlTimestamp().getYear()); + Assert.assertEquals(sqlTimestamp.getHours(), s.getSqlTimestamp().getHours()); + Assert.assertEquals(sqlTimestamp.getMinutes(), s.getSqlTimestamp().getMinutes()); + Assert.assertEquals(sqlTimestamp.getSeconds(), s.getSqlTimestamp().getSeconds()); + + Assert.assertEquals(Math.round(bigDecimal.doubleValue()), Math.round(s.getBigDecimal().doubleValue())); + Assert.assertEquals(bigInteger, s.getBigInteger()); + + Assert.assertEquals(calendar.get(Calendar.YEAR), s.getCalendar().get(Calendar.YEAR)); + Assert.assertEquals(calendar.get(Calendar.MONTH), s.getCalendar().get(Calendar.MONTH)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_YEAR), s.getCalendar().get(Calendar.WEEK_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_MONTH), s.getCalendar().get(Calendar.WEEK_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_MONTH), s.getCalendar().get(Calendar.DAY_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK), s.getCalendar().get(Calendar.DAY_OF_WEEK)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH), + s.getCalendar().get(Calendar.DAY_OF_WEEK_IN_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_YEAR), s.getCalendar().get(Calendar.DAY_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.HOUR), s.getCalendar().get(Calendar.HOUR)); + Assert.assertEquals(calendar.get(Calendar.HOUR_OF_DAY), s.getCalendar().get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(calendar.get(Calendar.AM), s.getCalendar().get(Calendar.AM)); + Assert.assertEquals(calendar.get(Calendar.PM), s.getCalendar().get(Calendar.PM)); + Assert.assertEquals(calendar.get(Calendar.AM_PM), s.getCalendar().get(Calendar.AM_PM)); + + Assert.assertEquals(new Integer(3), s.getYearsSpent()); + Assert.assertEquals(new Long(978423946455l), s.getRollNumber()); + Assert.assertEquals(new Double(135434.89), s.getMonthlyFee()); + + } + + abstract void startServer() throws InterruptedException; + + abstract void stopServer() throws InterruptedException, MasterNotRunningException, ZooKeeperConnectionException, + IOException; + + abstract void createSchema(); + + abstract void deleteSchema(); + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentEntityDef.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentEntityDef.java new file mode 100644 index 000000000..5e2071686 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentEntityDef.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +/** + * @author vivek.mishra + * + */ +public interface StudentEntityDef +{ + + /** + * @return the studentId + */ + long getStudentId(); + + /** + * @param studentId + * the studentId to set + */ + void setStudentId(long studentId); + + /** + * @return the uniqueId + */ + long getUniqueId(); + + /** + * @param uniqueId + * the uniqueId to set + */ + void setUniqueId(long uniqueId); + + /** + * @return the studentName + */ + String getStudentName(); + + /** + * @param studentName + * the studentName to set + */ + void setStudentName(String studentName); + + /** + * @return the isExceptional + */ + boolean isExceptional(); + + /** + * @param isExceptional + * the isExceptional to set + */ + void setExceptional(boolean isExceptional); + + /** + * @return the age + */ + int getAge(); + + /** + * @param age + * the age to set + */ + void setAge(int age); + + /** + * @return the semester + */ + char getSemester(); + + /** + * @param semester + * the semester to set + */ + void setSemester(char semester); + + /** + * @return the digitalSignature + */ + byte getDigitalSignature(); + + /** + * @param digitalSignature + * the digitalSignature to set + */ + void setDigitalSignature(byte digitalSignature); + + /** + * @return the cgpa + */ + short getCgpa(); + + /** + * @param cgpa + * the cgpa to set + */ + void setCgpa(short cgpa); + + /** + * @return the percentage + */ + float getPercentage(); + + /** + * @param percentage + * the percentage to set + */ + void setPercentage(float percentage); + + /** + * @return the height + */ + double getHeight(); + + /** + * @param height + * the height to set + */ + void setHeight(double height); + + /** + * @return the enrolmentDate + */ + java.util.Date getEnrolmentDate(); + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + void setEnrolmentDate(java.util.Date enrolmentDate); + + /** + * @return the enrolmentTime + */ + java.util.Date getEnrolmentTime(); + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + void setEnrolmentTime(java.util.Date enrolmentTime); + + /** + * @return the joiningDateAndTime + */ + java.util.Date getJoiningDateAndTime(); + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + void setJoiningDateAndTime(java.util.Date joiningDateAndTime); + + /** + * @return the yearsSpent + */ + Integer getYearsSpent(); + + /** + * @param yearsSpent + * the yearsSpent to set + */ + void setYearsSpent(Integer yearsSpent); + + /** + * @return the rollNumber + */ + Long getRollNumber(); + + /** + * @param rollNumber + * the rollNumber to set + */ + void setRollNumber(Long rollNumber); + + /** + * @return the monthlyFee + */ + Double getMonthlyFee(); + + /** + * @param monthlyFee + * the monthlyFee to set + */ + void setMonthlyFee(Double monthlyFee); + + java.sql.Date getSqlDate(); + + void setSqlDate(java.sql.Date sqlDate); + + /** + * @return the sqlTimestamp + */ + java.sql.Timestamp getSqlTimestamp(); + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + void setSqlTimestamp(java.sql.Timestamp sqlTimestamp); + + /** + * @return the sqlTime + */ + java.sql.Time getSqlTime(); + + /** + * @param sqlTime + * the sqlTime to set + */ + void setSqlTime(java.sql.Time sqlTime); + + /** + * @return the bigInteger + */ + BigInteger getBigInteger(); + + /** + * @param bigInteger + * the bigInteger to set + */ + void setBigInteger(BigInteger bigInteger); + + /** + * @return the bigDecimal + */ + BigDecimal getBigDecimal(); + + /** + * @param bigDecimal + * the bigDecimal to set + */ + void setBigDecimal(BigDecimal bigDecimal); + + /** + * @return the calendar + */ + Calendar getCalendar(); + + /** + * @param calendar + * the calendar to set + */ + void setCalendar(Calendar calendar); + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBase.java new file mode 100644 index 000000000..bdeae109f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBase.java @@ -0,0 +1,474 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +@Entity +@Table(name = "STUDENT", schema = "KunderaExamples@hbaseTest") +public class StudentHBase implements StudentEntityDef +{ + // Primitive Types + @Id + @Column(name = "STUDENT_ID") + private long studentId; + + @Column(name = "UNIQUE_ID") + private long uniqueId; + + @Column(name = "STUDENT_NAME") + private String studentName; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "AGE") + private int age; + + @Column(name = "SEMESTER") + private char semester; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "CGPA") + private short cgpa; // 1-10 + + @Column(name = "PERCENTAGE") + private float percentage; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "ROLL_NUMBER") + private Long rollNumber; + + @Column(name = "MONTHLY_FEE") + private Double monthlyFee; + + @Column(name = "SQL_DATE") + private java.sql.Date sqlDate; + + @Column(name = "SQL_TIMESTAMP") + private java.sql.Timestamp sqlTimestamp; + + @Column(name = "SQL_TIME") + private java.sql.Time sqlTime; + + @Column(name = "BIG_INT") + private BigInteger bigInteger; + + @Column(name = "BIG_DECIMAL") + private BigDecimal bigDecimal; + + @Column(name = "CALENDAR") + private Calendar calendar; + + /** + * @return the studentId + */ + public long getStudentId() + { + return studentId; + } + + /** + * @param studentId + * the studentId to set + */ + public void setStudentId(long studentId) + { + this.studentId = studentId; + } + + /** + * @return the uniqueId + */ + public long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the studentName + */ + public String getStudentName() + { + return studentName; + } + + /** + * @param studentName + * the studentName to set + */ + public void setStudentName(String studentName) + { + this.studentName = studentName; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the semester + */ + public char getSemester() + { + return semester; + } + + /** + * @param semester + * the semester to set + */ + public void setSemester(char semester) + { + this.semester = semester; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the cgpa + */ + public short getCgpa() + { + return cgpa; + } + + /** + * @param cgpa + * the cgpa to set + */ + public void setCgpa(short cgpa) + { + this.cgpa = cgpa; + } + + /** + * @return the percentage + */ + public float getPercentage() + { + return percentage; + } + + /** + * @param percentage + * the percentage to set + */ + public void setPercentage(float percentage) + { + this.percentage = percentage; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the rollNumber + */ + public Long getRollNumber() + { + return rollNumber; + } + + /** + * @param rollNumber + * the rollNumber to set + */ + public void setRollNumber(Long rollNumber) + { + this.rollNumber = rollNumber; + } + + /** + * @return the monthlyFee + */ + public Double getMonthlyFee() + { + return monthlyFee; + } + + /** + * @param monthlyFee + * the monthlyFee to set + */ + public void setMonthlyFee(Double monthlyFee) + { + this.monthlyFee = monthlyFee; + } + + public java.sql.Date getSqlDate() + { + return sqlDate; + } + + public void setSqlDate(java.sql.Date sqlDate) + { + this.sqlDate = sqlDate; + } + + /** + * @return the sqlTimestamp + */ + public java.sql.Timestamp getSqlTimestamp() + { + return sqlTimestamp; + } + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + public void setSqlTimestamp(java.sql.Timestamp sqlTimestamp) + { + this.sqlTimestamp = sqlTimestamp; + } + + /** + * @return the sqlTime + */ + public java.sql.Time getSqlTime() + { + return sqlTime; + } + + /** + * @param sqlTime + * the sqlTime to set + */ + public void setSqlTime(java.sql.Time sqlTime) + { + this.sqlTime = sqlTime; + } + + /** + * @return the bigInteger + */ + public BigInteger getBigInteger() + { + return bigInteger; + } + + /** + * @param bigInteger + * the bigInteger to set + */ + public void setBigInteger(BigInteger bigInteger) + { + this.bigInteger = bigInteger; + } + + /** + * @return the bigDecimal + */ + public BigDecimal getBigDecimal() + { + return bigDecimal; + } + + /** + * @param bigDecimal + * the bigDecimal to set + */ + public void setBigDecimal(BigDecimal bigDecimal) + { + this.bigDecimal = bigDecimal; + } + + /** + * @return the calendar + */ + public Calendar getCalendar() + { + return calendar; + } + + /** + * @param calendar + * the calendar to set + */ + public void setCalendar(Calendar calendar) + { + this.calendar = calendar; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigDecimalTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigDecimalTest.java new file mode 100644 index 000000000..731b22864 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigDecimalTest.java @@ -0,0 +1,572 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.math.BigDecimal; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseBigDecimal; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseBigDecimalTest extends Base +{ + private static final String table = "StudentHBaseBigDecimal"; + + private HBaseCli cli; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigDecimal + StudentHBaseBigDecimal studentMax = new StudentHBaseBigDecimal(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigDecimal) getMaxValue(BigDecimal.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigDecimal + StudentHBaseBigDecimal studentMin = new StudentHBaseBigDecimal(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((BigDecimal) getMinValue(BigDecimal.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigDecimal + StudentHBaseBigDecimal student = new StudentHBaseBigDecimal(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigDecimal) getRandomValue(BigDecimal.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBigDecimal studentMax = em.find(StudentHBaseBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigDecimal studentMin = em.find(StudentHBaseBigDecimal.class, getMinValue(BigDecimal.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigDecimal student = em.find(StudentHBaseBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseBigDecimal student = em.find(StudentHBaseBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigDecimal newStudent = em.find(StudentHBaseBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.id between " + getMinValue(BigDecimal.class) + " and " + + getMaxValue(BigDecimal.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBigDecimal student : students) + { + if (student.getId().equals(getRandomValue(BigDecimal.class))) + { + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBigDecimal studentMax = em.find(StudentHBaseBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseBigDecimal s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigDecimal newStudent = em.find(StudentHBaseBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseBigDecimal s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigDecimal newStudent = em.find(StudentHBaseBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Amresh and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigDecimal s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseBigDecimal s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigIntegerTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigIntegerTest.java new file mode 100644 index 000000000..b6dc0ff96 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBigIntegerTest.java @@ -0,0 +1,575 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.math.BigInteger; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseBigInteger; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseBigIntegerTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseBigInteger"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigInteger + StudentHBaseBigInteger studentMax = new StudentHBaseBigInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigInteger) getMaxValue(BigInteger.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigInteger + StudentHBaseBigInteger studentMin = new StudentHBaseBigInteger(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((BigInteger) getMinValue(BigInteger.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigInteger + StudentHBaseBigInteger student = new StudentHBaseBigInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigInteger) getRandomValue(BigInteger.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBigInteger studentMax = em.find(StudentHBaseBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigInteger studentMin = em.find(StudentHBaseBigInteger.class, getMinValue(BigInteger.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigInteger student = em.find(StudentHBaseBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseBigInteger student = em.find(StudentHBaseBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigInteger newStudent = em.find(StudentHBaseBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.id between " + getMinValue(BigInteger.class) + " and " + + getRandomValue(BigInteger.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBigInteger studentMax = em.find(StudentHBaseBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseBigInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigInteger newStudent = em.find(StudentHBaseBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseBigInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBigInteger newStudent = em.find(StudentHBaseBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Amresh and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBigInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseBigInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanPrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanPrimitiveTest.java new file mode 100644 index 000000000..956cf584f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanPrimitiveTest.java @@ -0,0 +1,557 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseBooleanPrimitive; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentHBaseBooleanPrimitiveTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseBooleanPrimitive"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of boolean + StudentHBaseBooleanPrimitive studentMax = new StudentHBaseBooleanPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of boolean + StudentHBaseBooleanPrimitive studentMin = new StudentHBaseBooleanPrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Boolean) getMinValue(boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBooleanPrimitive studentMax = em.find(StudentHBaseBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanPrimitive studentMin = em.find(StudentHBaseBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseBooleanPrimitive student = em.find(StudentHBaseBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanPrimitive newStudent = em.find(StudentHBaseBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(boolean.class)); + q.setParameter(2, getMaxValue(boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + int count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + // if (student.getId() == ((Boolean) + // getMaxValue(boolean.class)).booleanValue()) + // { + // Assert.assertEquals(getMaxValue(short.class), student.getAge()); + // Assert.assertEquals("Kuldeep", student.getName()); + // count++; + // } + // else if (student.getId() == ((Boolean) + // getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Kuldeep or s.age > " + getPartialValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("Unsupported clause OR for Hbase", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBooleanPrimitive studentMax = em.find(StudentHBaseBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getPartialValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseBooleanPrimitive s where s.id=true"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanPrimitive newStudent = em.find(StudentHBaseBooleanPrimitive.class, getRandomValue(boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseBooleanPrimitive s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanPrimitive newStudent = em.find(StudentHBaseBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Kuldeep and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.age = " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseBooleanPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanWrapperTest.java new file mode 100644 index 000000000..85a41f8f7 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBooleanWrapperTest.java @@ -0,0 +1,554 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseBooleanWrapper; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentHBaseBooleanWrapperTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseBooleanWrapper"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Boolean + StudentHBaseBooleanWrapper studentMax = new StudentHBaseBooleanWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(Boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Boolean + StudentHBaseBooleanWrapper studentMin = new StudentHBaseBooleanWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Boolean) getMinValue(Boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBooleanWrapper studentMax = em.find(StudentHBaseBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanWrapper studentMin = em.find(StudentHBaseBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseBooleanWrapper student = em.find(StudentHBaseBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanWrapper newStudent = em.find(StudentHBaseBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(Boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Boolean.class)); + q.setParameter(2, getMaxValue(Boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + int count = 0; + for (StudentHBaseBooleanWrapper student : students) + {/* + * if (student.getId().equals(getMaxValue(Boolean.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } else + */ + if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Kuldeep or s.age > " + getPartialValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("Unsupported clause OR for Hbase", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(Boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(Boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBooleanWrapper studentMax = em.find(StudentHBaseBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getPartialValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(Boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseBooleanWrapper s where s.id=true"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanWrapper newStudent = em.find(StudentHBaseBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseBooleanWrapper s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBooleanWrapper newStudent = em.find(StudentHBaseBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Kuldeep and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + if (student.getId() == ((Boolean) getMaxValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.age = " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBooleanWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseBooleanWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBytePrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBytePrimitiveTest.java new file mode 100644 index 000000000..38e002952 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseBytePrimitiveTest.java @@ -0,0 +1,583 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseBytePrimitive; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseBytePrimitiveTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseBytePrimitive"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of byte + StudentHBaseBytePrimitive studentMax = new StudentHBaseBytePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of byte + StudentHBaseBytePrimitive studentMin = new StudentHBaseBytePrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Byte) getMinValue(byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of byte + StudentHBaseBytePrimitive student = new StudentHBaseBytePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBytePrimitive studentMax = em.find(StudentHBaseBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBytePrimitive studentMin = em.find(StudentHBaseBytePrimitive.class, getMinValue(byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBytePrimitive student = em.find(StudentHBaseBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseBytePrimitive student = em.find(StudentHBaseBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBytePrimitive newStudent = em.find(StudentHBaseBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.id between " + getRandomValue(byte.class) + " and " + + getMinValue(byte.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId() == ((Byte) + // getMinValue(byte.class)).byteValue()) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseBytePrimitive studentMax = em.find(StudentHBaseBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseBytePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBytePrimitive newStudent = em.find(StudentHBaseBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseBytePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseBytePrimitive newStudent = em.find(StudentHBaseBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseBytePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseBytePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Byte) getMinValue(byte.class)).byteValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseByteWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseByteWrapperTest.java new file mode 100644 index 000000000..926ac7be8 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseByteWrapperTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseByteWrapper; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseByteWrapperTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseByteWrapper"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Byte + StudentHBaseByteWrapper studentMax = new StudentHBaseByteWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(Byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Byte + StudentHBaseByteWrapper studentMin = new StudentHBaseByteWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Byte) getMinValue(Byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Byte + StudentHBaseByteWrapper student = new StudentHBaseByteWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(Byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseByteWrapper studentMax = em.find(StudentHBaseByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseByteWrapper studentMin = em.find(StudentHBaseByteWrapper.class, getMinValue(Byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseByteWrapper student = em.find(StudentHBaseByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseByteWrapper student = em.find(StudentHBaseByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseByteWrapper newStudent = em.find(StudentHBaseByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.id between " + getRandomValue(Byte.class) + " and " + + getMinValue(Byte.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId().equals(getMinValue(Byte.class))) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseByteWrapper studentMax = em.find(StudentHBaseByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseByteWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseByteWrapper newStudent = em.find(StudentHBaseByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseByteWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseByteWrapper newStudent = em.find(StudentHBaseByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseByteWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseByteWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Byte.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCalendarTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCalendarTest.java new file mode 100644 index 000000000..edea40dc8 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCalendarTest.java @@ -0,0 +1,516 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.Calendar; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseCalendar; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentHBaseCalendarTest extends Base +{ + + private static final String table = "StudentHBaseCalendar"; + + private EntityManagerFactory emf; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Calendar + StudentHBaseCalendar studentMax = new StudentHBaseCalendar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId(((Calendar) getMaxValue(Calendar.class))); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseCalendar studentMax = em.find(StudentHBaseCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseCalendar student = em.find(StudentHBaseCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCalendar newStudent = em.find(StudentHBaseCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.age = " + getMaxValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.id between " + getRandomValue(Calendar.class) + " and " + + getMaxValue(Calendar.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseCalendar student : students) + { + if (student.getId().equals(getRandomValue(Calendar.class))) + { + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Calendar.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em = null; + String query; + Query q; + try + { + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for Hbase", qhe.getMessage()); + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Calendar + StudentHBaseCalendar studentMax = new StudentHBaseCalendar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId(((Calendar) getMaxValue(Calendar.class))); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + em.close(); + + em = emf.createEntityManager(); + + studentMax = em.find(StudentHBaseCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseCalendar s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCalendar newStudent = em.find(StudentHBaseCalendar.class, getRandomValue(Calendar.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseCalendar s SET s.name=Vivek where s.name=Kuldeep"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCalendar newStudent = em.find(StudentHBaseCalendar.class, getRandomValue(Calendar.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + if (student.getId().equals(getMaxValue(Calendar.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.age = " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCalendar s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCalendar student : students) + { + if (student.getId().equals(getMaxValue(Calendar.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseCalendar s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + int count = 0; + for (StudentHBaseCalendar student : students) + { + if (student.getId().equals(getMaxValue(Calendar.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharTest.java new file mode 100644 index 000000000..8ceb2048b --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharTest.java @@ -0,0 +1,579 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseChar; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseCharTest extends Base +{ + private static final String table = "StudentHBaseChar"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of char + StudentHBaseChar studentMax = new StudentHBaseChar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(char.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of char + StudentHBaseChar studentMin = new StudentHBaseChar(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Character) getMinValue(char.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of char + StudentHBaseChar student = new StudentHBaseChar(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(char.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseChar studentMax = em.find(StudentHBaseChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseChar studentMin = em.find(StudentHBaseChar.class, getMinValue(char.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseChar student = em.find(StudentHBaseChar.class, getRandomValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseChar student = em.find(StudentHBaseChar.class, getMaxValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseChar newStudent = em.find(StudentHBaseChar.class, getMaxValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.id between " + getMinValue(char.class) + " and " + + getMaxValue(char.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseChar student : students) + { + /* + * if (student.getId() == ((Character) + * getMaxValue(char.class)).charValue()) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseChar studentMax = em.find(StudentHBaseChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseChar.class, getMaxValue(char.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseChar s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseChar newStudent = em.find(StudentHBaseChar.class, getRandomValue(char.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseChar s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseChar newStudent = em.find(StudentHBaseChar.class, getRandomValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseChar s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseChar s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharacterTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharacterTest.java new file mode 100644 index 000000000..a44e363b6 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseCharacterTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseCharacter; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseCharacterTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseCharacter"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Character + StudentHBaseCharacter studentMax = new StudentHBaseCharacter(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(Character.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Character + StudentHBaseCharacter studentMin = new StudentHBaseCharacter(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Character) getMinValue(Character.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Character + StudentHBaseCharacter student = new StudentHBaseCharacter(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(Character.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseCharacter studentMax = em.find(StudentHBaseCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCharacter studentMin = em.find(StudentHBaseCharacter.class, getMinValue(Character.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCharacter student = em.find(StudentHBaseCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseCharacter student = em.find(StudentHBaseCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCharacter newStudent = em.find(StudentHBaseCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.id between " + getMinValue(Character.class) + " and " + + getMaxValue(Character.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseCharacter student : students) + { + // if (student.getId().equals(getMaxValue(Character.class))) + // { + // Assert.assertEquals(getMaxValue(short.class), student.getAge()); + // Assert.assertEquals("Kuldeep", student.getName()); + // count++; + // } + // else + if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseCharacter studentMax = em.find(StudentHBaseCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseCharacter.class, getMaxValue(Character.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseCharacter s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCharacter newStudent = em.find(StudentHBaseCharacter.class, getRandomValue(Character.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseCharacter s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseCharacter newStudent = em.find(StudentHBaseCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Amresh and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseCharacter s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseCharacter s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDateTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDateTest.java new file mode 100644 index 000000000..02518fc37 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDateTest.java @@ -0,0 +1,580 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseDate; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseDateTest extends Base +{ + private static final String table = "StudentHBaseDate"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentHBaseDate student = new StudentHBaseDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentHBaseDate studentMax = new StudentHBaseDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentHBaseDate studentMin = new StudentHBaseDate(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDate studentMax = em.find(StudentHBaseDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDate studentMin = em.find(StudentHBaseDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDate student = em.find(StudentHBaseDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseDate student = em.find(StudentHBaseDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDate newStudent = em.find(StudentHBaseDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.id between " + getMinValue(Date.class) + " and " + + getMaxValue(Date.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseDate student : students) + { + /* + * if (student.getId().equals(getMaxValue(Date.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDate studentMax = em.find(StudentHBaseDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDate newStudent = em.find(StudentHBaseDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDate newStudent = em.find(StudentHBaseDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoublePrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoublePrimitiveTest.java new file mode 100644 index 000000000..6a5377fff --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoublePrimitiveTest.java @@ -0,0 +1,580 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseDoublePrimitive; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseDoublePrimitiveTest extends Base +{ + private static final String table = "StudentHBaseDoublePrimitive"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentHBaseDoublePrimitive studentMax = new StudentHBaseDoublePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentHBaseDoublePrimitive studentMin = new StudentHBaseDoublePrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentHBaseDoublePrimitive student = new StudentHBaseDoublePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDoublePrimitive studentMax = em.find(StudentHBaseDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoublePrimitive studentMin = em.find(StudentHBaseDoublePrimitive.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoublePrimitive student = em.find(StudentHBaseDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseDoublePrimitive student = em.find(StudentHBaseDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoublePrimitive newStudent = em.find(StudentHBaseDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(double.class)); + q.setParameter(2, getMaxValue(double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + /* + * if (student.getId() == ((Double) + * getMaxValue(Double.class)).doubleValue()) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDoublePrimitive studentMax = em.find(StudentHBaseDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseDoublePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoublePrimitive newStudent = em.find(StudentHBaseDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseDoublePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoublePrimitive newStudent = em.find(StudentHBaseDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoublePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseDoublePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoubleWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoubleWrapperTest.java new file mode 100644 index 000000000..09d5d377e --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseDoubleWrapperTest.java @@ -0,0 +1,579 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseDoubleWrapper; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseDoubleWrapperTest extends Base +{ + private static final String table = "StudentHBaseDoubleWrapper"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentHBaseDoubleWrapper studentMax = new StudentHBaseDoubleWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentHBaseDoubleWrapper studentMin = new StudentHBaseDoubleWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentHBaseDoubleWrapper student = new StudentHBaseDoubleWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDoubleWrapper studentMax = em.find(StudentHBaseDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoubleWrapper studentMin = em.find(StudentHBaseDoubleWrapper.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoubleWrapper student = em.find(StudentHBaseDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseDoubleWrapper student = em.find(StudentHBaseDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoubleWrapper newStudent = em.find(StudentHBaseDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Double.class)); + q.setParameter(2, getMaxValue(Double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + /* + * if (student.getId().equals(getMaxValue(Double.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseDoubleWrapper studentMax = em.find(StudentHBaseDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseDoubleWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoubleWrapper newStudent = em.find(StudentHBaseDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseDoubleWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseDoubleWrapper newStudent = em.find(StudentHBaseDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseDoubleWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseDoubleWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatPrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatPrimitiveTest.java new file mode 100644 index 000000000..2d7bb20d4 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatPrimitiveTest.java @@ -0,0 +1,579 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseFloatPrimitive; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseFloatPrimitiveTest extends Base +{ + private static final String table = "StudentHBaseFloatPrimitive"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of float + StudentHBaseFloatPrimitive studentMax = new StudentHBaseFloatPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of float + StudentHBaseFloatPrimitive studentMin = new StudentHBaseFloatPrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Float) getMinValue(float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of float + StudentHBaseFloatPrimitive student = new StudentHBaseFloatPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseFloatPrimitive studentMax = em.find(StudentHBaseFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatPrimitive studentMin = em.find(StudentHBaseFloatPrimitive.class, getMinValue(float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatPrimitive student = em.find(StudentHBaseFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseFloatPrimitive student = em.find(StudentHBaseFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatPrimitive newStudent = em.find(StudentHBaseFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.id between " + getMinValue(float.class) + " and " + + getMaxValue(float.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + /* + * if (student.getId() == ((Float) + * getMaxValue(float.class)).floatValue()) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseFloatPrimitive studentMax = em.find(StudentHBaseFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseFloatPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatPrimitive newStudent = em.find(StudentHBaseFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseFloatPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatPrimitive newStudent = em.find(StudentHBaseFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseFloatPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatWrapperTest.java new file mode 100644 index 000000000..acfa7d8b1 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseFloatWrapperTest.java @@ -0,0 +1,578 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseFloatWrapper; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseFloatWrapperTest extends Base +{ + private static final String table = "StudentHBaseFloatWrapper"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Float + StudentHBaseFloatWrapper studentMax = new StudentHBaseFloatWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(Float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Float + StudentHBaseFloatWrapper studentMin = new StudentHBaseFloatWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Float) getMinValue(Float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Float + StudentHBaseFloatWrapper student = new StudentHBaseFloatWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(Float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseFloatWrapper studentMax = em.find(StudentHBaseFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatWrapper studentMin = em.find(StudentHBaseFloatWrapper.class, getMinValue(Float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatWrapper student = em.find(StudentHBaseFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseFloatWrapper student = em.find(StudentHBaseFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatWrapper newStudent = em.find(StudentHBaseFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.id between " + getMinValue(Float.class) + " and " + + getMaxValue(Float.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseFloatWrapper student : students) + { + /* + * if (student.getId().equals(getMaxValue(Float.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseFloatWrapper studentMax = em.find(StudentHBaseFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseFloatWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatWrapper newStudent = em.find(StudentHBaseFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseFloatWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseFloatWrapper newStudent = em.find(StudentHBaseFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseFloatWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseFloatWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntTest.java new file mode 100644 index 000000000..c2ba4fdb7 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntTest.java @@ -0,0 +1,603 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseInt; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseIntTest extends Base +{ + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseInt"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of int + StudentHBaseInt studentMax = new StudentHBaseInt(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(int.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert random value of int + StudentHBaseInt student = new StudentHBaseInt(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(int.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert min value of int + StudentHBaseInt studentMin = new StudentHBaseInt(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Integer) getMinValue(int.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseInt studentMax = em.find(StudentHBaseInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInt studentMin = em.find(StudentHBaseInt.class, getMinValue(int.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInt student = em.find(StudentHBaseInt.class, getRandomValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseInt student = em.find(StudentHBaseInt.class, getMaxValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInt newStudent = em.find(StudentHBaseInt.class, getMaxValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.id between " + getRandomValue(int.class) + " and " + + getMinValue(int.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId() == ((Integer) + // getMinValue(int.class)).intValue()) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseInt studentMax = em.find(StudentHBaseInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseInt.class, getMaxValue(int.class)); + Assert.assertNull(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + + StudentHBaseInt studentMin = em.find(StudentHBaseInt.class, getMinValue(int.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals("Kuldeep", studentMin.getName()); + em.remove(studentMin); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMin = em.find(StudentHBaseInt.class, getMinValue(int.class)); + Assert.assertNull(studentMin); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseInt s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInt newStudent = em.find(StudentHBaseInt.class, getRandomValue(int.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseInt s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInt newStudent = em.find(StudentHBaseInt.class, getRandomValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + // query = + // "Select s From StudentHBaseInt s where s.name = Amresh and s.age > ?1 and s.age < ?2"; + q = em.createQuery(query); + // q.setParameter(1, getPartialValue(short.class)); + // q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInt s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseInt s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Integer) getMinValue(int.class)).intValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntegerTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntegerTest.java new file mode 100644 index 000000000..748942e67 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseIntegerTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseInteger; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseIntegerTest extends Base +{ + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseInteger"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of integer + StudentHBaseInteger studentMax = new StudentHBaseInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(Integer.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of integer + StudentHBaseInteger studentMin = new StudentHBaseInteger(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Integer) getMinValue(Integer.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of integer + StudentHBaseInteger student = new StudentHBaseInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(Integer.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseInteger studentMax = em.find(StudentHBaseInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInteger studentMin = em.find(StudentHBaseInteger.class, getMinValue(Integer.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInteger student = em.find(StudentHBaseInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseInteger student = em.find(StudentHBaseInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInteger newStudent = em.find(StudentHBaseInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getRandomValue(Integer.class)); + q.setParameter(2, getMinValue(Integer.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId().equals(getMinValue(Integer.class))) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseInteger studentMax = em.find(StudentHBaseInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseInteger.class, getMaxValue(Integer.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInteger newStudent = em.find(StudentHBaseInteger.class, getRandomValue(Integer.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseInteger newStudent = em.find(StudentHBaseInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Integer.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongPrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongPrimitiveTest.java new file mode 100644 index 000000000..01b4d5420 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongPrimitiveTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseLongPrimitive; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseLongPrimitiveTest extends Base +{ + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseLongPrimitive"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of long + StudentHBaseLongPrimitive studentMax = new StudentHBaseLongPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of long + StudentHBaseLongPrimitive studentMin = new StudentHBaseLongPrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Long) getMinValue(long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of long + StudentHBaseLongPrimitive student = new StudentHBaseLongPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseLongPrimitive studentMax = em.find(StudentHBaseLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongPrimitive studentMin = em.find(StudentHBaseLongPrimitive.class, getMinValue(long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongPrimitive student = em.find(StudentHBaseLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseLongPrimitive student = em.find(StudentHBaseLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongPrimitive newStudent = em.find(StudentHBaseLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getRandomValue(long.class)); + q.setParameter(2, getMinValue(long.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId() == ((Long) + // getMinValue(long.class)).longValue()) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseLongPrimitive studentMax = em.find(StudentHBaseLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseLongPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongPrimitive newStudent = em.find(StudentHBaseLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseLongPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongPrimitive newStudent = em.find(StudentHBaseLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseLongPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Long) getMinValue(long.class)).longValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongWrapperTest.java new file mode 100644 index 000000000..e3ac99183 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseLongWrapperTest.java @@ -0,0 +1,581 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseLongWrapper; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseLongWrapperTest extends Base +{ + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseLongWrapper"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Long + StudentHBaseLongWrapper studentMax = new StudentHBaseLongWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(Long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Long + StudentHBaseLongWrapper studentMin = new StudentHBaseLongWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Long) getMinValue(Long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Long + StudentHBaseLongWrapper student = new StudentHBaseLongWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(Long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseLongWrapper studentMax = em.find(StudentHBaseLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongWrapper studentMin = em.find(StudentHBaseLongWrapper.class, getMinValue(Long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongWrapper student = em.find(StudentHBaseLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseLongWrapper student = em.find(StudentHBaseLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongWrapper newStudent = em.find(StudentHBaseLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getRandomValue(Long.class)); + q.setParameter(2, getMinValue(Long.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + // else if (student.getId().equals(getMinValue(Long.class))) + // { + // Assert.assertEquals(getPartialValue(short.class), + // student.getAge()); + // Assert.assertEquals(getMinValue(String.class), + // student.getName()); + // count++; + // } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseLongWrapper studentMax = em.find(StudentHBaseLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseLongWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongWrapper newStudent = em.find(StudentHBaseLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseLongWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseLongWrapper newStudent = em.find(StudentHBaseLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseLongWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseLongWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Long.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortPrimitiveTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortPrimitiveTest.java new file mode 100644 index 000000000..bd58fe097 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortPrimitiveTest.java @@ -0,0 +1,580 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseShortPrimitive; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseShortPrimitiveTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseShortPrimitive"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentHBaseShortPrimitive studentMax = new StudentHBaseShortPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentHBaseShortPrimitive studentMin = new StudentHBaseShortPrimitive(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Short) getPartialValue(short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentHBaseShortPrimitive student = new StudentHBaseShortPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseShortPrimitive studentMax = em.find(StudentHBaseShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortPrimitive studentMin = em.find(StudentHBaseShortPrimitive.class, getPartialValue(short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortPrimitive student = em.find(StudentHBaseShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseShortPrimitive student = em.find(StudentHBaseShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortPrimitive newStudent = em.find(StudentHBaseShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.id between " + getPartialValue(short.class) + " and " + + getMaxValue(Short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseShortPrimitive student : students) + { + /* + * if (student.getId() == ((Short) + * getMaxValue(Short.class)).shortValue()) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId() == ((Short) getPartialValue(short.class)).shortValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseShortPrimitive studentMax = em.find(StudentHBaseShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseShortPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortPrimitive newStudent = em.find(StudentHBaseShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseShortPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortPrimitive newStudent = em.find(StudentHBaseShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseShortPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Short) getPartialValue(short.class)).shortValue()) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortWrapperTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortWrapperTest.java new file mode 100644 index 000000000..9c885065f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseShortWrapperTest.java @@ -0,0 +1,579 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseShortWrapper; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseShortWrapperTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseShortWrapper"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentHBaseShortWrapper studentMax = new StudentHBaseShortWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentHBaseShortWrapper studentMin = new StudentHBaseShortWrapper(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Short) getPartialValue(short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentHBaseShortWrapper student = new StudentHBaseShortWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseShortWrapper studentMax = em.find(StudentHBaseShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortWrapper studentMin = em.find(StudentHBaseShortWrapper.class, getPartialValue(short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortWrapper student = em.find(StudentHBaseShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseShortWrapper student = em.find(StudentHBaseShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortWrapper newStudent = em.find(StudentHBaseShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.id between " + getPartialValue(short.class) + " and " + + getMaxValue(Short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseShortWrapper student : students) + { + /* + * if (student.getId().equals(getMaxValue(Short.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId().equals(getPartialValue(short.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseShortWrapper studentMax = em.find(StudentHBaseShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseShortWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortWrapper newStudent = em.find(StudentHBaseShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseShortWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseShortWrapper newStudent = em.find(StudentHBaseShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseShortWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getPartialValue(short.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseShortWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getPartialValue(short.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseSqlDateTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseSqlDateTest.java new file mode 100644 index 000000000..361637bb4 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseSqlDateTest.java @@ -0,0 +1,583 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.sql.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseSqlDate; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseSqlDateTest extends Base +{ + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseSqlDate"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentHBaseSqlDate student = new StudentHBaseSqlDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentHBaseSqlDate studentMax = new StudentHBaseSqlDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentHBaseSqlDate studentMin = new StudentHBaseSqlDate(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseSqlDate studentMax = em.find(StudentHBaseSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseSqlDate studentMin = em.find(StudentHBaseSqlDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseSqlDate student = em.find(StudentHBaseSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseSqlDate student = em.find(StudentHBaseSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseSqlDate newStudent = em.find(StudentHBaseSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.id between " + getMinValue(Date.class) + " and " + + getMaxValue(Date.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseSqlDate studentMax = em.find(StudentHBaseSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseSqlDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseSqlDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseSqlDate newStudent = em.find(StudentHBaseSqlDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseSqlDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseSqlDate newStudent = em.find(StudentHBaseSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseSqlDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseSqlDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseStringTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseStringTest.java new file mode 100644 index 000000000..23be82ac2 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseStringTest.java @@ -0,0 +1,571 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseString; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseStringTest extends Base +{ + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + private static final String table = "StudentHBaseString"; + + private HBaseCli cli; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of String + StudentHBaseString studentMax = new StudentHBaseString(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((String) getMaxValue(String.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of String + StudentHBaseString studentMin = new StudentHBaseString(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((String) getMinValue(String.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of String + StudentHBaseString student = new StudentHBaseString(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((String) getRandomValue(String.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseString studentMax = em.find(StudentHBaseString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseString studentMin = em.find(StudentHBaseString.class, getMinValue(String.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseString student = em.find(StudentHBaseString.class, getRandomValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseString student = em.find(StudentHBaseString.class, getMaxValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseString newStudent = em.find(StudentHBaseString.class, getMaxValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.id between " + getRandomValue(String.class) + " and " + + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseString student : students) + { + if (student.getId().equals(getRandomValue(String.class))) + { + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseString studentMax = em.find(StudentHBaseString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseString.class, getMaxValue(String.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseString s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseString newStudent = em.find(StudentHBaseString.class, getRandomValue(String.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseString s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseString newStudent = em.find(StudentHBaseString.class, getRandomValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.age > " + getPartialValue(short.class) + " and s.age < " + + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseString s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseString s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(String.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTest.java new file mode 100644 index 000000000..44920b269 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTest.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.crud.datatypes; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.List; + +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.MasterNotRunningException; +import org.apache.hadoop.hbase.ZooKeeperConnectionException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; + +/** + * The Class Student test case for HBase. + * + * @author Kuldeep.mishra + */ +public class StudentHBaseTest extends StudentBase +{ + private String persistenceUnit = "hbaseTest"; + + private HBaseCli cli; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + setupInternal(persistenceUnit); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + teardownInternal(persistenceUnit); + + } + + @Test + public void executeTests() + { + onInsert(); + onMerge(); + } + + /** + * Test method for. + * + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + * {@link com.impetus.kundera.examples.student.StudentDao#saveStudent(com.impetus.kundera.StudentHBase.crud.datatype.entities.StudentHbase)} + * . + */ + + public void onInsert() + { + try + { + onInsert(new StudentHBase()); + } + catch (InstantiationException e) + { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + catch (IllegalAccessException e) + { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + // find by id. + StudentEntityDef s = em.find(StudentHBase.class, studentId1); + assertOnDataTypes((StudentHBase) s); + + // // find by name. + assertFindByName(em, "StudentHBase", StudentHBase.class, "Amresh", "studentName"); + + // find by name and age. + assertFindByNameAndAge(em, "StudentHBase", StudentHBase.class, "Amresh", "10", "studentName"); + + // find by name, age clause + assertFindByNameAndAgeGTAndLT(em, "StudentHBase", StudentHBase.class, "Amresh", "10", "20", "studentName"); + // + // // find by between clause + assertFindByNameAndAgeBetween(em, "StudentHBase", StudentHBase.class, "Amresh", "10", "15", "studentName"); + + // find by Range. + assertFindByRange(em, "StudentHBase", StudentHBase.class, "12345677", "12345679", "studentId"); + + // find by without where clause. + assertFindWithoutWhereClause(em, "StudentHBase", StudentHBase.class); + + // Query on Date. + String query = "Select s from StudentHBase s where s.enrolmentDate =:enrolmentDate"; + Query q = em.createQuery(query); + q.setParameter("enrolmentDate", enrolmentDate); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + // Query on long. + /* String */query = "Select s from StudentHBase s where s.uniqueId =?1"; + /* Query */q = em.createQuery(query); + q.setParameter(1, 78575785897L); + + /* List */results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + + // Assert on boolean. + query = "Select s from StudentHBase s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, true); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(true, results.get(0).isExceptional()); + + // with false. + query = "Select s from StudentHBase s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, false); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + + // query on int. + + query = "Select s from StudentHBase s where s.age =?1"; + q = em.createQuery(query); + q.setParameter(1, 10); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + + // query on char (semester) + + query = "Select s from StudentHBase s where s.semester =?1"; + q = em.createQuery(query); + q.setParameter(1, 'A'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals('A', results.get(0).getSemester()); + + // query on float (percentage) + query = "Select s from StudentHBase s where s.percentage =?1"; + q = em.createQuery(query); + q.setParameter(1, 61.6); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + + // query on double (height) + + query = "Select s from StudentHBase s where s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on cgpa. + query = "Select s from StudentHBase s where s.cgpa =?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(8, results.get(0).getCgpa()); + + // query on yearsSpent. + Integer i = new Integer(3); + query = "Select s from StudentHBase s where s.yearsSpent = 3"; + q = em.createQuery(query); + // q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(i, results.get(0).getYearsSpent()); + + // query on yearsSpent. + query = "Select s from StudentHBase s where s.yearsSpent =?1"; + q = em.createQuery(query); + q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(new Integer(3), results.get(0).getYearsSpent()); + + // query on digitalSignature. + query = "Select s from StudentHBase s where s.digitalSignature =?1"; + q = em.createQuery(query); + q.setParameter(1, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(true, results.get(0).isExceptional()); + Assert.assertEquals((byte) 50, results.get(0).getDigitalSignature()); + + // query on cpga and digitalSignature. + query = "Select s from StudentHBase s where s.cgpa =?1 and s.digitalSignature >= ?2 and s.digitalSignature <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + + // query on cpga and digitalSignature parameter appended with String + // . + query = "Select s from StudentHBase s where s.cgpa = 8 and s.digitalSignature >= 5 and s.digitalSignature <= 50"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + + // query on cpga and digitalSignature. + query = "Select s from StudentHBase s where s.digitalSignature >= ?2 and s.digitalSignature <= ?3 and s.cgpa =?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + + // query on percentage and height. + query = "Select s from StudentHBase s where s.percentage >= ?2 and s.percentage <= ?3 and s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + q.setParameter(2, 61.6); + q.setParameter(3, 69.3); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on percentage and height parameter appended in string. + query = "Select s from StudentHBase s where s.percentage >= 61.6 and s.percentage <= 69.3 and s.height = 163.76765654"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on cpga and uniqueId. + query = "Select s from StudentHBase s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + Assert.assertEquals(78575785898L, results.get(1).getUniqueId()); + + // query on cpga and semester. + query = "Select s from StudentHBase s where s.cgpa =?1 and s.semester >= ?2 and s.semester < ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 'A'); + q.setParameter(3, 'C'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + Assert.assertEquals(78575785898L, results.get(1).getUniqueId()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals(20, results.get(1).getAge()); + + // query on cpga and semester with appending in string. + query = "Select s from StudentHBase s where s.cgpa = 8 and s.semester >= A and s.semester < C"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + Assert.assertEquals(78575785898L, results.get(1).getUniqueId()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals(20, results.get(1).getAge()); + + // query on invalid cpga and uniqueId. + query = "Select s from StudentHBase s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 2); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + // query on big integer. + query = "Select s from StudentHBase s where s.bigInteger =?1"; + q = em.createQuery(query); + q.setParameter(1, bigInteger); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + Assert.assertEquals(true, results.get(1).isExceptional()); + Assert.assertEquals(163.76765655, results.get(1).getHeight()); + Assert.assertEquals(true, results.get(2).isExceptional()); + Assert.assertEquals(163.76765656, results.get(2).getHeight()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals(20, results.get(1).getAge()); + Assert.assertEquals(15, results.get(2).getAge()); + Assert.assertEquals('A', results.get(0).getSemester()); + Assert.assertEquals('B', results.get(1).getSemester()); + Assert.assertEquals('C', results.get(2).getSemester()); + + // invalid. + q.setParameter(1, new BigInteger("1234567823")); + results = q.getResultList(); + + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + updateQueryTest(); + + } + + private void updateQueryTest() + {/* + * Query q = em.createQuery( + * "update StudentHBase s set s.studentName = :oldName where s.studentName = :newName" + * ); q.setParameter("newName", "NewAmresh"); q.setParameter("oldName", + * "Amresh"); int results = q.executeUpdate(); + * Assert.assertNotNull(results); Assert.assertEquals(1, results); + */ + } + + /** + * On merge. + */ + public void onMerge() + { + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", true, 10, 'C', (byte) 5, (short) 8, + (float) 69.6, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + new StudentHBase())); + StudentHBase s = em.find(StudentHBase.class, studentId1); + Assert.assertNotNull(s); + Assert.assertEquals("Amresh", s.getStudentName()); + // modify record. + s.setStudentName("NewAmresh"); + em.merge(s); + // emf.close(); + Query q = em.createQuery("Select p from StudentHBase p where p.studentName = NewAmresh"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + } + + @Override + void startServer() throws InterruptedException + { + cli = new HBaseCli(); + cli.startCluster(); + } + + @Override + void stopServer() throws InterruptedException, MasterNotRunningException, ZooKeeperConnectionException, IOException + { + } + + @Override + void createSchema() + { + cli.createTable("STUDENT"); + } + + @Override + void deleteSchema() + { + cli.dropTable("NETSTAT_DTL_SMRY"); + cli.dropTable("STUDENT"); + cli.dropTable("PERSON_HBASE"); + cli.dropTable("PERSON"); + cli.dropTable("Address"); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimeTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimeTest.java new file mode 100644 index 000000000..73a4adf05 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimeTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.sql.Time; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseTime; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseTimeTest extends Base +{ + private static final String table = "StudentHBaseTime"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentHBaseTime student = new StudentHBaseTime(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Time) getRandomValue(Time.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentHBaseTime studentMax = new StudentHBaseTime(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Time) getMaxValue(Time.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Time + StudentHBaseTime studentMin = new StudentHBaseTime(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Time) getMinValue(Time.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseTime studentMax = em.find(StudentHBaseTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTime studentMin = em.find(StudentHBaseTime.class, getMinValue(Time.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTime student = em.find(StudentHBaseTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseTime student = em.find(StudentHBaseTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTime newStudent = em.find(StudentHBaseTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.id between " + getMinValue(Time.class) + " and " + + getMaxValue(Time.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseTime studentMax = em.find(StudentHBaseTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseTime.class, getMaxValue(Time.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseTime s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTime newStudent = em.find(StudentHBaseTime.class, getRandomValue(Time.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentHBaseTime s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTime newStudent = em.find(StudentHBaseTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTime s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseTime s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Time) getRandomValue(Time.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimestampTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimestampTest.java new file mode 100644 index 000000000..6c662c2c0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseTimestampTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.sql.Timestamp; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseTimestamp; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseTimestampTest extends Base +{ + private static final String table = "StudentHBaseTimestamp"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentHBaseTimestamp student = new StudentHBaseTimestamp(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Timestamp) getRandomValue(Timestamp.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentHBaseTimestamp studentMax = new StudentHBaseTimestamp(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Timestamp) getMaxValue(Timestamp.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Timestamp + StudentHBaseTimestamp studentMin = new StudentHBaseTimestamp(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((Timestamp) getMinValue(Timestamp.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseTimestamp studentMax = em.find(StudentHBaseTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTimestamp studentMin = em.find(StudentHBaseTimestamp.class, getMinValue(Timestamp.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTimestamp student = em.find(StudentHBaseTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseTimestamp student = em.find(StudentHBaseTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTimestamp newStudent = em.find(StudentHBaseTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.id between " + getMinValue(Timestamp.class) + " and " + + getMaxValue(Timestamp.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentHBaseTimestamp student : students) + { + /* + * if (student.getId().equals(getMaxValue(Timestamp.class))) { + * Assert.assertEquals(getMaxValue(short.class), student.getAge()); + * Assert.assertEquals("Kuldeep", student.getName()); count++; } + * else + */if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseTimestamp studentMax = em.find(StudentHBaseTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseTimestamp s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTimestamp newStudent = em.find(StudentHBaseTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentHBaseTimestamp s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseTimestamp newStudent = em.find(StudentHBaseTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Amresh and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseTimestamp s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseTimestamp s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Timestamp) getRandomValue(Timestamp.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseUUIDTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseUUIDTest.java new file mode 100644 index 000000000..02810d68f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/StudentHBaseUUIDTest.java @@ -0,0 +1,580 @@ +package com.impetus.client.hbase.crud.datatypes; + +import java.util.List; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.datatypes.entities.StudentHBaseUUID; +import com.impetus.client.hbase.junits.HBaseCli; + +public class StudentHBaseUUIDTest extends Base +{ + private static final String table = "StudentHBaseUUID"; + + private HBaseCli cli; + + private static final String keyspace = "KunderaHbaseDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("HbaseDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of UUID + StudentHBaseUUID studentMax = new StudentHBaseUUID(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((UUID) getMaxValue(UUID.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of UUID + StudentHBaseUUID studentMin = new StudentHBaseUUID(); + studentMin.setAge((Short) getPartialValue(short.class)); + studentMin.setId((UUID) getMinValue(UUID.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of UUID + StudentHBaseUUID student = new StudentHBaseUUID(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((UUID) getRandomValue(UUID.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseUUID studentMax = em.find(StudentHBaseUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseUUID studentMin = em.find(StudentHBaseUUID.class, getMinValue(UUID.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getPartialValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseUUID student = em.find(StudentHBaseUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentHBaseUUID student = em.find(StudentHBaseUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseUUID newStudent = em.find(StudentHBaseUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.age = " + getPartialValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMaxValue(UUID.class)); + q.setParameter(2, getRandomValue(UUID.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Kuldeep and s.age > " + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Kuldeep and s.age > " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentHBaseUUID studentMax = em.find(StudentHBaseUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentHBaseUUID.class, getMaxValue(UUID.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentHBaseUUID s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseUUID newStudent = em.find(StudentHBaseUUID.class, getRandomValue(UUID.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentHBaseUUID s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentHBaseUUID newStudent = em.find(StudentHBaseUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Amresh and s.age > " + getPartialValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Kuldeep and s.age >= " + getPartialValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentHBaseUUID s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentHBaseUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentHBaseUUID s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentHBaseUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + cli = new HBaseCli(); + cli.startCluster(); + } + + public void stopCluster() + { + cli.stopCluster(); + } + + public void createSchema() + { + cli.createTable(table); + + } + + public void dropSchema() + { + cli.dropTable(table); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/ZkShutDownTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/ZkShutDownTest.java new file mode 100644 index 000000000..3c202d25d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/ZkShutDownTest.java @@ -0,0 +1,39 @@ +/** + * + */ +package com.impetus.client.hbase.crud.datatypes; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Kuldeep Mishra + * + */ +public class ZkShutDownTest +{ + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + @Test + public void test() + { + // HBaseCli.cleanUp(); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigDecimal.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigDecimal.java new file mode 100644 index 000000000..c61eee360 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigDecimal.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseBigDecimal", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseBigDecimal +{ + + @Id + private BigDecimal id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigDecimal getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigDecimal id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigInteger.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigInteger.java new file mode 100644 index 000000000..413d7ba9b --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBigInteger.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.math.BigInteger; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseBigInteger", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseBigInteger +{ + + @Id + private BigInteger id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigInteger getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigInteger id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanPrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanPrimitive.java new file mode 100644 index 000000000..93461e2a0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanPrimitive.java @@ -0,0 +1,72 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseBooleanPrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseBooleanPrimitive +{ + @Id + private boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanWrapper.java new file mode 100644 index 000000000..e522611a5 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBooleanWrapper.java @@ -0,0 +1,72 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseBooleanWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseBooleanWrapper +{ + @Id + private Boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBytePrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBytePrimitive.java new file mode 100644 index 000000000..41a262503 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseBytePrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseBytePrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseBytePrimitive +{ + + @Id + private byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseByteWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseByteWrapper.java new file mode 100644 index 000000000..63b5661b9 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseByteWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseByteWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseByteWrapper +{ + + @Id + private Byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCalendar.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCalendar.java new file mode 100644 index 000000000..65e258ba9 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCalendar.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseCalendar", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseCalendar +{ + + @Id + private Calendar id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Calendar getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Calendar id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseChar.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseChar.java new file mode 100644 index 000000000..8da515386 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseChar.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseChar", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseChar +{ + + @Id + private char id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public char getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(char id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCharacter.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCharacter.java new file mode 100644 index 000000000..609ba375e --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseCharacter.java @@ -0,0 +1,72 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseCharacter", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseCharacter +{ + @Id + private Character id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Character getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Character id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDate.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDate.java new file mode 100644 index 000000000..2ca1b08af --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDate.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseDate", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoublePrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoublePrimitive.java new file mode 100644 index 000000000..f6896c3ab --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoublePrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseDoublePrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseDoublePrimitive +{ + + @Id + private double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoubleWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoubleWrapper.java new file mode 100644 index 000000000..e8065c941 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseDoubleWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseDoubleWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseDoubleWrapper +{ + + @Id + private Double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatPrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatPrimitive.java new file mode 100644 index 000000000..fdbb072fd --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatPrimitive.java @@ -0,0 +1,72 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseFloatPrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseFloatPrimitive +{ + @Id + private float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatWrapper.java new file mode 100644 index 000000000..7877d4766 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseFloatWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseFloatWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseFloatWrapper +{ + + @Id + private Float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInt.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInt.java new file mode 100644 index 000000000..8bf83fd8d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInt.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseInt", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseInt +{ + + @Id + private int id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInteger.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInteger.java new file mode 100644 index 000000000..7a79eaa11 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseInteger.java @@ -0,0 +1,72 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseInteger", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseInteger +{ + @Id + private Integer id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Integer getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Integer id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongPrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongPrimitive.java new file mode 100644 index 000000000..3a8cfdfe8 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongPrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseLongPrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseLongPrimitive +{ + + @Id + private long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongWrapper.java new file mode 100644 index 000000000..9e5fe1c7e --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseLongWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseLongWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseLongWrapper +{ + + @Id + private Long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortPrimitive.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortPrimitive.java new file mode 100644 index 000000000..5ca0a509f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortPrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseShortPrimitive", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseShortPrimitive +{ + + @Id + private short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortWrapper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortWrapper.java new file mode 100644 index 000000000..6f020e4e6 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseShortWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseShortWrapper", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseShortWrapper +{ + + @Id + private Short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseSqlDate.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseSqlDate.java new file mode 100644 index 000000000..10460e978 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseSqlDate.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.sql.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseSqlDate", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseSqlDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseString.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseString.java new file mode 100644 index 000000000..46af20876 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseString.java @@ -0,0 +1,73 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseString", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseString +{ + + @Id + private String id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTime.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTime.java new file mode 100644 index 000000000..ec6635ecf --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTime.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.sql.Time; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseTime", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseTime +{ + + @Id + private Time id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Time getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Time id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTimestamp.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTimestamp.java new file mode 100644 index 000000000..7b5bb477d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseTimestamp.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.sql.Timestamp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseTimestamp", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseTimestamp +{ + + @Id + private Timestamp id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Timestamp getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Timestamp id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseUUID.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseUUID.java new file mode 100644 index 000000000..22a25511a --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/datatypes/entities/StudentHBaseUUID.java @@ -0,0 +1,75 @@ +package com.impetus.client.hbase.crud.datatypes.entities; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentHBaseUUID", schema = "KunderaHbaseDataType@HbaseDataTypeTest") +public class StudentHBaseUUID +{ + + @Id + private UUID id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public UUID getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(UUID id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/EmbeddedEntityTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/EmbeddedEntityTest.java new file mode 100644 index 000000000..b65a043aa --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/EmbeddedEntityTest.java @@ -0,0 +1,243 @@ +package com.impetus.client.hbase.crud.embedded; + +import java.io.IOException; +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.servlet.UnavailableException; + +import org.apache.thrift.TException; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +public class EmbeddedEntityTest +{ + + /** + * + */ + private static final Date CAPTURE_TIME = new Date(); + + private static final Date CAPTURE_TIME1 = new Date("Feb 14 10:01:25 MST 2010"); + + private static final Date CAPTURE_TIME2 = new Date(Long.MAX_VALUE); + + private static final Date CAPTURE_TIME3 = new Date("Feb 14 10:10:17 MST 2016"); + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + private static HBaseCli cli; + + @BeforeClass + public static void setUpBeforeClass() throws IOException + { + cli = new HBaseCli(); + cli.startCluster(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + } + + @Before + public void setUp() throws IOException, TException, UnavailableException + { + em = emf.createEntityManager(); + } + + @Test + public void testSelectEmbeddedColumn() + { + persist(); + String query2 = "select x.id," + "x.rowKey," + "x.established, " + "x.closeWait," + "x.finWait," + + "x.finWait2," + "x.idle," + "x.listen," + "x.synRecv," + "x.timeWait," + "x.total " + + "from NetstatData x " + "where x.id.server= :serverid"; + + Query query = em.createQuery(query2); + query.setParameter("serverid", "apdwa570"); + List result = query.getResultList(); + Assert.assertNotNull(result); + Assert.assertEquals(2, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(0).getId()); + Assert.assertEquals(CAPTURE_TIME, result.get(0).getId().getCaptureTime()); + Assert.assertEquals("apdwa570", result.get(0).getId().getServer()); + Assert.assertNull(result.get(0).getId().getPortMapId()); + } + + @Test + public void testSelectOnlySpecificColumnOfEmbeddable() + { + persist(); + String query2 = "select x.id.captureTime," + "x.rowKey," + "x.established, " + "x.closeWait," + "x.finWait," + + "x.finWait2," + "x.idle," + "x.listen," + "x.synRecv," + "x.timeWait," + "x.total " + + "from NetstatData x " + "where x.id.server= :serverid"; + + Query query = em.createQuery(query2); + query.setParameter("serverid", "apdwa571"); + List result = query.getResultList(); + Assert.assertNotNull(result); + Assert.assertEquals(2, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(0).getId()); + Assert.assertEquals(CAPTURE_TIME2, result.get(0).getId().getCaptureTime()); + Assert.assertNull(result.get(0).getId().getServer()); + Assert.assertNull(result.get(0).getId().getPortMapId()); + } + + @Test + public void testSelectTwoSpecificColumnOfEmbeddable() + { + persist(); + String query2 = "select x.id.captureTime," + "x.id.server," + "x.rowKey," + "x.established, " + "x.closeWait," + + "x.finWait," + "x.finWait2," + "x.idle," + "x.listen," + "x.synRecv," + "x.timeWait," + "x.total " + + "from NetstatData x " + "where x.id.portMapTypeCd= :port" + + " and x.id.captureTime between :captureTime1 and :captureTime2"; + + Query query = em.createQuery(query2); + query.setParameter("port", "portMapTypeCd"); + query.setParameter("captureTime1", CAPTURE_TIME1); + query.setParameter("captureTime2", CAPTURE_TIME3); + + List result = query.getResultList(); + Assert.assertNotNull(result); + Assert.assertEquals(3, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(0).getId()); + Assert.assertEquals(CAPTURE_TIME, result.get(0).getId().getCaptureTime()); + Assert.assertEquals("apdwa570", result.get(0).getId().getServer()); + Assert.assertNull(result.get(0).getId().getPortMapId()); + } + + @Test + public void testSelectTwoColumnsOfEmbeddable() + { + persist(); + String query2 = "select x.id.captureTime," + "x.id.server," + "x.rowKey," + "x.established, " + "x.closeWait," + + "x.finWait," + "x.finWait2," + "x.idle," + "x.listen," + "x.synRecv," + "x.timeWait," + "x.total " + + "from NetstatData x " + "where x.id.server= :serverId" + + " and x.id.captureTime between :captureTime1 and :captureTime2"; + + Query query = em.createQuery(query2); + query.setParameter("serverId", "apdwa571"); + query.setParameter("captureTime1", CAPTURE_TIME1); + query.setParameter("captureTime2", CAPTURE_TIME3); + + List result = query.getResultList(); + Assert.assertNotNull(result); + Assert.assertEquals(1, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(0).getId()); + Assert.assertEquals(CAPTURE_TIME3, result.get(0).getId().getCaptureTime()); + Assert.assertEquals("apdwa571", result.get(0).getId().getServer()); + Assert.assertNull(result.get(0).getId().getPortMapId()); + } + + @Test + public void testSelectAll() + { + persist(); + String query2 = "select x from NetstatData x " + "where x.id.portMapTypeCd= :port"; + + Query query = em.createQuery(query2); + query.setParameter("port", "portMapTypeCd"); + List result = query.getResultList(); + Assert.assertNotNull(result); + Assert.assertEquals(4, result.size()); + Assert.assertNotNull(result.get(0)); + Assert.assertNotNull(result.get(0).getId()); + Assert.assertEquals(CAPTURE_TIME, result.get(0).getId().getCaptureTime()); + Assert.assertEquals("apdwa570", result.get(0).getId().getServer()); + Assert.assertNull(result.get(0).getId().getPortMapId()); + } + + @After + public void tearDown() + { + em.close(); + + } + + @AfterClass + public static void tearDownAfterClass() + { + emf.close(); + if (cli != null ) + { + cli.dropTable("NETSTAT_DTL_SMRY"); + cli.dropTable("STUDENT"); + cli.dropTable("PERSON_HBASE"); + cli.dropTable("PERSON"); + cli.dropTable("Address"); + } + } + + /** + * + */ + private void persist() + { + NetstatData data = new NetstatData(); + NetstatDataId id = new NetstatDataId(); + id.setServer("apdwa570"); + data.setRowKey("rowKey1"); + id.setCaptureTime(CAPTURE_TIME); + id.setPortMapTypeCd("portMapTypeCd"); + data.setEstablished(1); + data.setTotal(1); + data.setId(id); + + em.persist(data); + + NetstatData data1 = new NetstatData(); + NetstatDataId id1 = new NetstatDataId(); + id1.setServer("apdwa570"); + data1.setRowKey("rowKey2"); + id1.setCaptureTime(CAPTURE_TIME1); + id1.setPortMapTypeCd("portMapTypeCd"); + data1.setEstablished(2); + data1.setTotal(2); + data1.setId(id1); + + em.persist(data1); + + NetstatData data2 = new NetstatData(); + NetstatDataId id2 = new NetstatDataId(); + id2.setServer("apdwa571"); + data2.setRowKey("rowKey3"); + id2.setCaptureTime(CAPTURE_TIME2); + id2.setPortMapTypeCd("portMapTypeCd"); + data2.setEstablished(3); + data2.setTotal(3); + data2.setId(id2); + + em.persist(data2); + + NetstatData data3 = new NetstatData(); + NetstatDataId id3 = new NetstatDataId(); + id3.setServer("apdwa571"); + data3.setRowKey("rowKey4"); + id3.setCaptureTime(CAPTURE_TIME3); + id3.setPortMapTypeCd("portMapTypeCd"); + data3.setEstablished(4); + data3.setTotal(4); + data3.setId(id3); + + em.persist(data3); + + em.clear(); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatData.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatData.java new file mode 100644 index 000000000..d524a485a --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatData.java @@ -0,0 +1,217 @@ +package com.impetus.client.hbase.crud.embedded; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@SuppressWarnings("serial") +@Entity +@Table(name = "NETSTAT_DTL_SMRY", schema = "KunderaExamples@hbaseTest") +public class NetstatData implements Serializable +{ + + @Id + @Column(name = "ROW_KEY") + private String rowKey; // added for hbase + + @Embedded + private NetstatDataId id; + + @Column(name = "ESTAB_PORT_CT", nullable = true) + private Integer established; + + @Column(name = "CLOSE_WAIT_CT", nullable = true) + private Integer closeWait; + + @Column(name = "FINISH_WAIT_CT", nullable = true) + private Integer finWait; + + @Column(name = "FINISH_WAIT2_CT", nullable = true) + private Integer finWait2; + + @Column(name = "IDLE_CT", nullable = true) + private Integer idle; + + @Column(name = "LISTEN_CT", nullable = true) + private Integer listen; + + @Column(name = "SYNC_RCV_CT", nullable = true) + private Integer synRecv; + + @Column(name = "TIME_WAIT_CT", nullable = true) + private Integer timeWait; + + @Column(name = "PORT_CT", nullable = true) + private Integer total; + + public NetstatData() + { + NetstatDataId id = new NetstatDataId(); + this.id = id; + } + + private transient String portDesc; + + public NetstatDataId getId() + { + return this.id; + } + + public void setId(NetstatDataId id) + { + this.id = id; + } + + public Integer getEstablished() + { + return this.established; + } + + public void setEstablished(Integer established) + { + this.established = established; + } + + public Integer getCloseWait() + { + return this.closeWait; + } + + public void setCloseWait(Integer closeWait) + { + this.closeWait = closeWait; + } + + public Integer getFinWait() + { + return this.finWait; + } + + public void setFinWait(Integer finWait) + { + this.finWait = finWait; + } + + public Integer getFinWait2() + { + return this.finWait2; + } + + public void setFinWait2(Integer finWait2) + { + this.finWait2 = finWait2; + } + + public Integer getIdle() + { + return this.idle; + } + + public void setIdle(Integer idle) + { + this.idle = idle; + } + + public Integer getListen() + { + return this.listen; + } + + public void setListen(Integer listen) + { + this.listen = listen; + } + + public Integer getSynRecv() + { + return this.synRecv; + } + + public void setSynRecv(Integer synRecv) + { + this.synRecv = synRecv; + } + + public Integer getTimeWait() + { + return this.timeWait; + } + + public void setTimeWait(Integer timeWait) + { + this.timeWait = timeWait; + } + + public Integer getTotal() + { + return this.total; + } + + public void setTotal(Integer total) + { + this.total = total; + } + + public String getPortDesc() + { + return portDesc; + } + + public void setPortDesc(String portDesc) + { + this.portDesc = portDesc; + } + + public String getPortType() + { + // For DataPower return PortMapTypeCd itself + if (id.getPortMapTypeCd().length() > 1) + { + return id.getPortMapTypeCd(); + } + + if (id.getPortMapTypeCd() == null) + return "Others"; + + switch (id.getPortMapTypeCd().toCharArray()[0]) + { + case 'A': + return "App Port"; + case 'N': + return "Netscaler"; + case 'W': + return "Web Port"; + case 'Q': + return "MQ"; + case 'D': + return "DB"; + case 'L': + return "Local"; + case '?': + return "?"; + default: + return "Others"; + } + + } + + public void setPortType(String s) + { + throw new IllegalArgumentException("Can't set a read-only attribute"); + } + + public String getRowKey() + { + return rowKey; + } + + public void setRowKey(String rowKey) + { + this.rowKey = rowKey; + } + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatDataId.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatDataId.java new file mode 100644 index 000000000..ae152b6a2 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/crud/embedded/NetstatDataId.java @@ -0,0 +1,93 @@ +package com.impetus.client.hbase.crud.embedded; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@SuppressWarnings("serial") +@Embeddable +public class NetstatDataId implements Serializable +{ + + @Column(name = "SERVER_ID", nullable = true) + private String server; + + @Column(name = "CPTR_TS", nullable = true) + private Date captureTime; + + @Column(name = "PORTMAP_ID", nullable = true) + private Integer portMapId; + + @Column(name = "PORTMAP_TYP_CD", nullable = true) + private String portMapTypeCd; + + public String getServer() + { + return this.server; + } + + public void setServer(String server) + { + this.server = server; + } + + public Date getCaptureTime() + { + return this.captureTime; + } + + public void setCaptureTime(Date captureTime) + { + this.captureTime = captureTime; + } + + public Integer getPortMapId() + { + return portMapId; + } + + public void setPortMapId(Integer portMapId) + { + this.portMapId = portMapId; + } + + public String getPortMapTypeCd() + { + return portMapTypeCd; + } + + public void setPortMapTypeCd(String portMapTypeCd) + { + this.portMapTypeCd = portMapTypeCd; + } + + public boolean equals(Object o) + { + if (this == o) + return true; + if (o == null) + return false; + if (!(o instanceof NetstatDataId)) + return false; + NetstatDataId that = (NetstatDataId) o; + + return ((server == that.server) || (server != null && that.server != null && server.equals(that.server))) + && ((captureTime == that.captureTime) || (captureTime != null && that.captureTime != null && captureTime + .equals(that.captureTime))) + && ((portMapId == that.portMapId) || (portMapId != null && that.portMapId != null && this.portMapId + .equals(that.portMapId))) && ((portMapTypeCd == that.portMapTypeCd)); + } + + public int hashCode() + { + int result = 17; + result = 37 * result + (server == null ? 0 : server.hashCode()); + result = 37 * result + (captureTime == null ? 0 : captureTime.hashCode()); + result = 37 * result + (portMapId == null ? 0 : portMapId.hashCode()); + result = 37 * result + (portMapTypeCd == null ? 0 : portMapTypeCd.hashCode()); + return result; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/HBaseGeneratedIdTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/HBaseGeneratedIdTest.java new file mode 100644 index 000000000..1452071c9 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/HBaseGeneratedIdTest.java @@ -0,0 +1,226 @@ +package com.impetus.client.hbase.generatedId; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.GenerationType; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.hbase.HBaseClient; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdDefault; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdStrategyAuto; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdStrategyIdentity; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdStrategySequence; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdStrategyTable; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdWithOutSequenceGenerator; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdWithOutTableGenerator; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdWithSequenceGenerator; +import com.impetus.client.hbase.generatedId.entites.HBaseGeneratedIdWithTableGenerator; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.KunderaException; + +public class HBaseGeneratedIdTest +{ + private EntityManagerFactory emf; + + private HBaseCli cli; + + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbase_generated_id"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + cli.dropTable("HBaseGeneratedIdDefault"); + cli.dropTable("HBaseGeneratedIdStrategyAuto"); + cli.dropTable("HBaseGeneratedIdStrategyIdentity"); + cli.dropTable("HBaseGeneratedIdStrategySequence"); + cli.dropTable("HBaseGeneratedIdStrategyTable"); + cli.dropTable("HBaseGeneratedIdWithOutSequenceGenerator"); + cli.dropTable("HBaseGeneratedIdWithOutTableGenerator"); + cli.dropTable("HBaseGeneratedIdWithSequenceGenerator"); + cli.dropTable("HBaseGeneratedIdWithTableGenerator"); + cli.dropTable("kunderahbase"); + cli.dropTable("kundera_sequences"); + } + + @Test + public void testPersist() + { + EntityManager em = emf.createEntityManager(); + + HBaseGeneratedIdDefault idDefault = new HBaseGeneratedIdDefault(); + idDefault.setName("kuldeep"); + try + { + em.persist(idDefault); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals("java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.AUTO + " Strategy not supported by this client :" + HBaseClient.class.getName(), + e.getMessage()); + } + HBaseGeneratedIdStrategyAuto strategyAuto = new HBaseGeneratedIdStrategyAuto(); + strategyAuto.setName("kuldeep"); + try + { + em.persist(strategyAuto); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals("java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.AUTO + " Strategy not supported by this client :" + HBaseClient.class.getName(), + e.getMessage()); + } + + HBaseGeneratedIdStrategyIdentity strategyIdentity = new HBaseGeneratedIdStrategyIdentity(); + strategyIdentity.setName("kuldeep"); + try + { + em.persist(strategyIdentity); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.UnsupportedOperationException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.IDENTITY + " Strategy not supported by this client :" + + HBaseClient.class.getName(), e.getMessage()); + } + + HBaseGeneratedIdStrategySequence strategySequence = new HBaseGeneratedIdStrategySequence(); + strategySequence.setName("Kuldeep"); + try + { + em.persist(strategySequence); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + HBaseClient.class.getName(), e.getMessage()); + } + + HBaseGeneratedIdStrategyTable strategyTable = new HBaseGeneratedIdStrategyTable(); + strategyTable.setName("KK"); + try + { + em.persist(strategyTable); + List list = em.createQuery("Select c from HBaseGeneratedIdStrategyTable c") + .getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("KK", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + strategyTable = em.find(HBaseGeneratedIdStrategyTable.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("KK", strategyTable.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + + HBaseGeneratedIdWithOutSequenceGenerator withOutSequenceGenerator = new HBaseGeneratedIdWithOutSequenceGenerator(); + withOutSequenceGenerator.setName("Kuldeep Kumar"); + try + { + em.persist(withOutSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + HBaseClient.class.getName(), e.getMessage()); + } + + HBaseGeneratedIdWithOutTableGenerator withOutTableGenerator = new HBaseGeneratedIdWithOutTableGenerator(); + withOutTableGenerator.setName("Kuldeep Mishra"); + try + { + em.persist(withOutTableGenerator); + List list = em.createQuery( + "Select c from HBaseGeneratedIdWithOutTableGenerator c").getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("Kuldeep Mishra", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + withOutTableGenerator = em.find(HBaseGeneratedIdWithOutTableGenerator.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("Kuldeep Mishra", withOutTableGenerator.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + HBaseGeneratedIdWithSequenceGenerator withSequenceGenerator = new HBaseGeneratedIdWithSequenceGenerator(); + withSequenceGenerator.setName("Kuldeep Kumar Mishra"); + try + { + em.persist(withSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + HBaseClient.class.getName(), e.getMessage()); + } + HBaseGeneratedIdWithTableGenerator withTableGenerator = new HBaseGeneratedIdWithTableGenerator(); + withTableGenerator.setName("Kumar Mishra"); + try + { + em.persist(withTableGenerator); + List list = em.createQuery( + "Select c from HBaseGeneratedIdWithTableGenerator c").getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("Kumar Mishra", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + withTableGenerator = em.find(HBaseGeneratedIdWithTableGenerator.class, id); + Assert.assertNotNull(strategyTable); + Assert.assertEquals("Kumar Mishra", withTableGenerator.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdDefault.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdDefault.java new file mode 100644 index 000000000..2135d0d73 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdDefault.java @@ -0,0 +1,53 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdDefault", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdDefault +{ + @Id + @GeneratedValue + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyAuto.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyAuto.java new file mode 100644 index 000000000..155d9d8fe --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyAuto.java @@ -0,0 +1,57 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "HBaseGeneratedIdStrategyAuto", schema = "kundera@hbase_generated_id") +@TableGenerator(name = "id_gen") +public class HBaseGeneratedIdStrategyAuto +{ + @Id + @GeneratedValue(generator = "id_gen", strategy = GenerationType.AUTO) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyIdentity.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyIdentity.java new file mode 100644 index 000000000..2c3862f3f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyIdentity.java @@ -0,0 +1,56 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdStrategyIdentity", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdStrategyIdentity +{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategySequence.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategySequence.java new file mode 100644 index 000000000..a50457292 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategySequence.java @@ -0,0 +1,57 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdStrategySequence", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdStrategySequence +{ + @Id + @SequenceGenerator(name = "seq_gen") + @GeneratedValue(generator = "seq_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyTable.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyTable.java new file mode 100644 index 000000000..23b7528e6 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdStrategyTable.java @@ -0,0 +1,59 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "HBaseGeneratedIdStrategyTable", schema = "kundera@hbase_generated_id") +@TableGenerator(name = "table_gen") +public class HBaseGeneratedIdStrategyTable +{ + + @Id + @TableGenerator(name = "table_gen_1") + @GeneratedValue(generator = "table_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutSequenceGenerator.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutSequenceGenerator.java new file mode 100644 index 000000000..dae301d4d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdWithOutSequenceGenerator", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdWithOutSequenceGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutTableGenerator.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutTableGenerator.java new file mode 100644 index 000000000..a05c6a886 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithOutTableGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdWithOutTableGenerator", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdWithOutTableGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithSequenceGenerator.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithSequenceGenerator.java new file mode 100644 index 000000000..c16f3f359 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "HBaseGeneratedIdWithSequenceGenerator", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdWithSequenceGenerator +{ + @Id + @SequenceGenerator(name = "id_gen", allocationSize = 20, initialValue = 80, schema = "kundera", sequenceName = "newSequence") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithTableGenerator.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithTableGenerator.java new file mode 100644 index 000000000..cc8c9e490 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/generatedId/entites/HBaseGeneratedIdWithTableGenerator.java @@ -0,0 +1,57 @@ +package com.impetus.client.hbase.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "HBaseGeneratedIdWithTableGenerator", schema = "kundera@hbase_generated_id") +public class HBaseGeneratedIdWithTableGenerator +{ + + @Id + @TableGenerator(name = "id_gen", allocationSize = 30, initialValue = 100, schema = "kundera", table = "kunderahbase", pkColumnName = "sequence", valueColumnName = "sequenceValue", pkColumnValue = "kk") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/junits/HBaseCli.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/junits/HBaseCli.java new file mode 100644 index 000000000..3a908b5e0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/junits/HBaseCli.java @@ -0,0 +1,341 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.junits; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.Socket; +import java.net.UnknownHostException; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.FileUtil; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HConstants; +import org.apache.hadoop.hbase.InvalidFamilyOperationException; +import org.apache.hadoop.hbase.client.HTablePool; +import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Embedded HBase client. + * + * @author vivek.mishra + * + */ +public class HBaseCli +{ + /** The utility. */ + public static HBaseTestingUtility utility; + + private static final Logger logger = LoggerFactory.getLogger(HBaseCli.class); + + private static File zkDir; + + private static File masterDir; + + private MiniZooKeeperCluster zkCluster; + + private HTablePool hTablePool; + + public static void main(String arg[]) + { + HBaseCli cli = new HBaseCli(); + cli.startCluster(); + } + + public void startCluster() + { + File workingDirectory = new File("./"); + Configuration conf = new Configuration(); + System.setProperty("test.build.data", workingDirectory.getAbsolutePath()); + conf.set("test.build.data", new File(workingDirectory, "zookeeper").getAbsolutePath()); + conf.set("fs.default.name", "file:///"); + conf.set("zookeeper.session.timeout", "180000"); + conf.set("hbase.zookeeper.peerport", "2888"); + conf.set("hbase.zookeeper.property.clientPort", "2181"); + // conf.set("dfs.datanode.data.dir.perm", "700"); + try + { + masterDir = new File(workingDirectory, "hbase"); + conf.set(HConstants.HBASE_DIR, masterDir.toURI().toURL().toString()); + } + catch (MalformedURLException e1) + { + logger.error(e1.getMessage()); + } + + Configuration hbaseConf = HBaseConfiguration.create(conf); + utility = new HBaseTestingUtility(hbaseConf); + + // Change permission for dfs.data.dir, please refer + // https://issues.apache.org/jira/browse/HBASE-5711 for more details. + try + { + Process process = Runtime.getRuntime().exec("/bin/sh -c umask"); + BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream())); + int rc = process.waitFor(); + if (rc == 0) + { + String umask = br.readLine(); + + int umaskBits = Integer.parseInt(umask, 8); + int permBits = 0777 & ~umaskBits; + String perms = Integer.toString(permBits, 8); + + logger.info("Setting dfs.datanode.data.dir.perm to " + perms); + utility.getConfiguration().set("dfs.datanode.data.dir.perm", perms); + } + else + { + logger.warn("Failed running umask command in a shell, nonzero return value"); + } + } + catch (Exception e) + { + // ignore errors, we might not be running on POSIX, or "sh" might + // not be on the path + logger.warn("Couldn't get umask", e); + } + if (!checkIfServerRunning()) + { + hTablePool = new HTablePool(conf, 1); + try + { + zkCluster = new MiniZooKeeperCluster(conf); + zkCluster.setDefaultClientPort(2181); + zkCluster.setTickTime(18000); + // utility.setupClusterTestDir(); + zkDir = new File(utility.getClusterTestDir().toString()); + + zkCluster.startup(zkDir); + utility.setZkCluster(zkCluster); + utility.startMiniCluster(); + utility.getHBaseCluster().startMaster(); + } + catch (Exception e) + { + e.printStackTrace(); + logger.error(e.getMessage()); + throw new RuntimeException(e); + } + } + } + + /** + * Creates the table. + * + * @param tableName + * the table name + */ + public void createTable(String tableName) + { + try + { + if (!utility.getHBaseAdmin().tableExists(tableName)) + { + utility.createTable(tableName.getBytes(), tableName.getBytes()); + if (utility.getHBaseAdmin().isTableDisabled(tableName)) + { + utility.getHBaseAdmin().enableTable(tableName); + } + } + else + { + logger.info("Table:" + tableName + " already exist:"); + } + } + catch (IOException e) + { + logger.error(e.getMessage()); + } + } + + public void createTable(byte[] tableName, byte[][] families) + { + try + { + utility.createTable(tableName, families); + } + catch (IOException e) + { + + } + } + + /** + * Adds the column family. + * + * @param tableName + * the table name + * @param columnFamily + * the column family + */ + public void addColumnFamily(String tableName, String columnFamily) + { + try + { + utility.getHBaseAdmin().disableTable(tableName); + utility.getHBaseAdmin().addColumn(tableName, new HColumnDescriptor(columnFamily)); + utility.getHBaseAdmin().enableTable(tableName); + while (utility.getHBaseAdmin().isTableEnabled(columnFamily)) + { + return; + } + + } + catch (InvalidFamilyOperationException ife) + { + logger.info("Column family:" + columnFamily + " already exist!", ife); + } + catch (IOException e) + { + logger.error("", e); + } + } + + public void dropTable(String tableName) + { + try + { + utility.getHBaseAdmin().disableTable(tableName); + utility.getHBaseAdmin().deleteTable(tableName); + } + catch (IOException e) + { + logger.error(e.getMessage()); + } + } + + /** + * Destroys cluster. + */ + public static void stopCluster(String... tableName) + { + // try + // { + // if (utility != null) + // { + // // utility.getMiniHBaseCluster().shutdown(); + // // File workingDirectory = new File("./"); + // // utility.closeRegion("localhost"); + // utility.cleanupTestDir(); + // // utility.cleanupTestDir(dir.getAbsolutePath()); + // // ZooKeeperServer server = new ZooKeeperServer(zkDir, zkDir, + // // 2000); + // // ZooKeeperServerBean bean = new ZooKeeperServerBean(server); + // // String path = (String)this.makeFullPath(null,bean); + // + // // MBeanS + // // MBeanRegistry.getInstance().unregister(bean); + // // MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + // // mbs.unregisterMBean(makeObjectName(path,bean)); + // // utility.getHbaseCluster().shutdown(); + // utility.shutdownMiniCluster(); + // FileUtil.fullyDelete(zkDir); + // FileUtil.fullyDelete(masterDir); + // utility = null; + // isStarted = false; + // } + // } + // catch (IOException e) + // { + // logger.error(e.getMessage()); + // } + // catch (NullPointerException e) + // { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // catch (Exception e) + // { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // + } + + public static void cleanUp() + { + try + { + if (utility != null) + { + // utility.getMiniHBaseCluster().shutdown(); + // File workingDirectory = new File("./"); + // utility.closeRegion("localhost"); + utility.cleanupTestDir(); + // utility.cleanupTestDir(dir.getAbsolutePath()); + // ZooKeeperServer server = new ZooKeeperServer(zkDir, zkDir, + // 2000); + // ZooKeeperServerBean bean = new ZooKeeperServerBean(server); + // String path = (String)this.makeFullPath(null,bean); + + // MBeanS + // MBeanRegistry.getInstance().unregister(bean); + // MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + // mbs.unregisterMBean(makeObjectName(path,bean)); + // utility.getHbaseCluster().shutdown(); + utility.shutdownMiniCluster(); + FileUtil.fullyDelete(zkDir); + FileUtil.fullyDelete(masterDir); + utility = null; + } + } + catch (IOException e) + { + logger.error(e.getMessage()); + } + catch (NullPointerException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + + /** + * Check if server running. + * + * @return true, if successful + */ + private static boolean checkIfServerRunning() + { + try + { + Socket socket = new Socket("127.0.0.1", 2181); + return socket.getInetAddress() != null; + } + catch (UnknownHostException e) + { + return false; + } + catch (IOException e) + { + return false; + } + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1.java new file mode 100644 index 000000000..578e5b6f6 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntityAddressUni1To1. + */ +@Entity +@Table(name = "HbaseEntityAddressUni1To1", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityAddressUni1To1 +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1PK.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1PK.java new file mode 100644 index 000000000..866fc6201 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1To1PK.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntityAddressUni1To1PK. + */ +@Entity +@Table(name = "HbaseEntityAddressUni1To1PK", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityAddressUni1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The address id. */ + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1ToM.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1ToM.java new file mode 100644 index 000000000..d2e0ba6fa --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUni1ToM.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntityAddressUni1ToM. + */ +@Entity +@Table(name = "HbaseEntityAddressUni1ToM", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityAddressUni1ToM +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUniMTo1.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUniMTo1.java new file mode 100644 index 000000000..90115410b --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityAddressUniMTo1.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntityAddressUniMTo1. + */ +@Entity +@Table(name = "HbaseEntityAddressUniMTo1", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityAddressUniMTo1 +{ + + /** The address id. */ + @Id + @Column(name = "ADDRESS_ID") + private String addressId; + + /** The street. */ + @Column(name = "STREET") + private String street; + + /** + * Gets the address id. + * + * @return the address id + */ + public String getAddressId() + { + return addressId; + } + + /** + * Sets the address id. + * + * @param addressId + * the new address id + */ + public void setAddressId(String addressId) + { + this.addressId = addressId; + } + + /** + * Gets the street. + * + * @return the street + */ + public String getStreet() + { + return street; + } + + /** + * Sets the street. + * + * @param street + * the new street + */ + public void setStreet(String street) + { + this.street = street; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1.java new file mode 100644 index 000000000..68c5fbad2 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * The Class HbaseEntityPersonUni1To1. + */ +@Entity +@Table(name = "HbaseEntityPersonUni1To1", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityPersonUni1To1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private HBasePersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private HBaseEntityAddressUni1To1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public HBasePersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(HBasePersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public HBaseEntityAddressUni1To1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(HBaseEntityAddressUni1To1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1PK.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1PK.java new file mode 100644 index 000000000..db5cbd092 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1To1PK.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; + +/** + * The Class HbaseEntityPersonUni1To1PK. + */ +@Entity +@Table(name = "HbaseEntityPersonUni1To1PK", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityPersonUni1To1PK +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The personal data. */ + @Embedded + HBasePersonalData personalData; + + /** The address. */ + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) + @PrimaryKeyJoinColumn + private HBaseEntityAddressUni1To1PK address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public HBasePersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(HBasePersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public HBaseEntityAddressUni1To1PK getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(HBaseEntityAddressUni1To1PK address) + { + this.address = address; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1ToM.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1ToM.java new file mode 100644 index 000000000..0e634cf9f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUni1ToM.java @@ -0,0 +1,165 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * The Class HbaseEntityPersonUni1ToM. + */ +@Entity +@Table(name = "HbaseEntityPersonUni1ToM", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityPersonUni1ToM +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private HBasePersonalData personalData; + + /** The addresses. */ + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "PERSON_ID") + private Set addresses; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public HBasePersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(HBasePersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the addresses. + * + * @return the addresses + */ + public Set getAddresses() + { + return addresses; + } + + /** + * Sets the addresses. + * + * @param addresses + * the addresses to set + */ + public void setAddresses(Set addresses) + { + this.addresses = addresses; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUniMto1.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUniMto1.java new file mode 100644 index 000000000..3f863bace --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntityPersonUniMto1.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class HbaseEntityPersonUniMto1. + */ +@Entity +@Table(name = "HbaseEntityPersonUniMto1", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntityPersonUniMto1 +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private HBasePersonalData personalData; + + /** The address. */ + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "ADDRESS_ID") + private HBaseEntityAddressUniMTo1 address; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public HBasePersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(HBasePersonalData personalData) + { + this.personalData = personalData; + } + + /** + * Gets the address. + * + * @return the address + */ + public HBaseEntityAddressUniMTo1 getAddress() + { + return address; + } + + /** + * Sets the address. + * + * @param address + * the address to set + */ + public void setAddress(HBaseEntityAddressUniMTo1 address) + { + this.address = address; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySimple.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySimple.java new file mode 100644 index 000000000..8ff0d8c6d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySimple.java @@ -0,0 +1,108 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntitySimple. + */ +@Entity +@Table(name = "HbaseEntitySimple", schema = "KunderaHbaseTests@HBaseSchemaOperationTest") +public class HBaseEntitySimple +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySuper.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySuper.java new file mode 100644 index 000000000..5070d4710 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseEntitySuper.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class HbaseEntitySuper. + */ +@Entity +@Table(name = "HbaseEntitySuper", schema = "KunderaHbaseExamples@hbase") +public class HBaseEntitySuper +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** The personal data. */ + @Embedded + private HBasePersonalData personalData; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * Gets the personal data. + * + * @return the personalData + */ + public HBasePersonalData getPersonalData() + { + return personalData; + } + + /** + * Sets the personal data. + * + * @param personalData + * the personalData to set + */ + public void setPersonalData(HBasePersonalData personalData) + { + this.personalData = personalData; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseGeneratedIdSchemaTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseGeneratedIdSchemaTest.java new file mode 100644 index 000000000..a13c2b77f --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseGeneratedIdSchemaTest.java @@ -0,0 +1,82 @@ +package com.impetus.client.hbase.schemaManager; + +import java.io.IOException; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; + +public class HBaseGeneratedIdSchemaTest +{ + private EntityManagerFactory emf; + + private HBaseCli cli; + + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbase_generated_id"); + } + + @After + public void tearDown() throws Exception + { + emf.close(); + cli.dropTable("HBaseGeneratedIdDefault"); + cli.dropTable("HBaseGeneratedIdStrategyAuto"); + cli.dropTable("HBaseGeneratedIdStrategyIdentity"); + cli.dropTable("HBaseGeneratedIdStrategySequence"); + cli.dropTable("HBaseGeneratedIdStrategyTable"); + cli.dropTable("HBaseGeneratedIdWithOutSequenceGenerator"); + cli.dropTable("HBaseGeneratedIdWithOutTableGenerator"); + cli.dropTable("HBaseGeneratedIdWithSequenceGenerator"); + cli.dropTable("HBaseGeneratedIdWithTableGenerator"); + cli.dropTable("kunderahbase"); + cli.dropTable("kundera_sequences"); + } + + @Test + public void test() + { + try + { + HBaseAdmin admin = HBaseCli.utility.getHBaseAdmin(); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdDefault".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdStrategyAuto".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdStrategyIdentity".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdStrategySequence".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdStrategyTable".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdWithOutSequenceGenerator".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdWithOutTableGenerator".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdWithSequenceGenerator".getBytes())); + Assert.assertTrue(admin.isTableAvailable("HBaseGeneratedIdWithTableGenerator".getBytes())); + Assert.assertTrue(admin.isTableAvailable("kunderahbase".getBytes())); + Assert.assertTrue(admin.isTableAvailable("kundera_sequences".getBytes())); + } + catch (IOException e) + { + Assert.fail(); + } + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBasePersonalData.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBasePersonalData.java new file mode 100644 index 000000000..9bd514f34 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBasePersonalData.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.hbase.schemaManager; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * The Class HbasePersonalData. + */ +@Embeddable +public class HBasePersonalData +{ + + /** The website. */ + @Column(name = "p_website") + private String website; + + /** The email. */ + @Column(name = "p_email") + private String email; + + /** The yahoo id. */ + @Column(name = "p_yahoo_id") + private String yahooId; + + /** + * Instantiates a new hbase personal data. + */ + public HBasePersonalData() + { + + } + + /** + * Instantiates a new hbase personal data. + * + * @param website + * the website + * @param email + * the email + * @param yahooId + * the yahoo id + */ + public HBasePersonalData(String website, String email, String yahooId) + { + this.website = website; + this.email = email; + this.yahooId = yahooId; + } + + /** + * Gets the website. + * + * @return the website + */ + public String getWebsite() + { + return website; + } + + /** + * Sets the website. + * + * @param website + * the new website + */ + public void setWebsite(String website) + { + this.website = website; + } + + /** + * Gets the email. + * + * @return the email + */ + public String getEmail() + { + return email; + } + + /** + * Sets the email. + * + * @param email + * the email to set + */ + public void setEmail(String email) + { + this.email = email; + } + + /** + * Gets the yahoo id. + * + * @return the yahoo id + */ + public String getYahooId() + { + return yahooId; + } + + /** + * Sets the yahoo id. + * + * @param yahooId + * the new yahoo id + */ + public void setYahooId(String yahooId) + { + this.yahooId = yahooId; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaManagerTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaManagerTest.java new file mode 100644 index 000000000..59001e3a0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaManagerTest.java @@ -0,0 +1,262 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import junit.framework.Assert; + +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * HbaseSchemaManagerTest class test the auto creation schema property in hbase + * data store. + * + * @author Kuldeep.Kumar + * + */ +public class HBaseSchemaManagerTest +{ + private final boolean useLucene = true; + + /** The configuration. */ + private SchemaConfiguration configuration; + + /** The admin. */ + private static HBaseAdmin admin; + + private ApplicationMetadata appMetadata; + + private HBaseCli cli; + + private String persistenceUnit = "hbase"; + + /** The Constant logger. */ + private static final Logger logger = LoggerFactory.getLogger(HBaseSchemaManagerTest.class); + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + cli = new HBaseCli(); + logger.info("starting server"); + // if (!HBaseCli.isStarted) + cli.startCluster(); + if (admin == null) + { + admin = cli.utility.getHBaseAdmin(); + } + configuration = new SchemaConfiguration(null, "hbase"); + + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + // if (HBaseCli.isStarted) +// cli.dropTable("HbaseEntitySimple"); + cli.stopCluster(); + appMetadata = null; + } + + @Test + public void testDu() + { + + } + + /** + * Test schema operation. + */ + // @Test + public void testSchemaOperation() + { + try + { + getEntityManagerFactory("create"); + Assert.assertTrue(admin.isTableAvailable("HbaseEntitySimple")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntitySuper")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityAddressUni1To1")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityAddressUniMTo1")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityAddressUni1ToM")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityPersonUni1ToM")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityPersonUni1To1")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityPersonUniMto1")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityAddressUni1To1PK")); + Assert.assertTrue(admin.isTableAvailable("HbaseEntityPersonUni1To1PK")); + } + catch (IOException e) + { + Assert.fail("Failed, Caused by:" + e.getMessage()); + } + catch (Exception e) + { + Assert.fail("Failed, Caused by:" + e.getMessage()); + } + } + + /** + * Gets the entity manager factory. + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + ClientMetadata clientMetadata = new ClientMetadata(); + Map props = new HashMap(); + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "9160"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaHbaseExamples"); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, "com.impetus.client.hbase.HBaseClientFactory"); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "/home/impadmin/lucene"); + + clientMetadata.setLuceneIndexDir("/home/impadmin/lucene"); + } + else + { + + clientMetadata.setLuceneIndexDir(null); + } + + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put("hbase", puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(HBaseEntitySimple.class.getName(), pus); + clazzToPu.put(HBaseEntitySuper.class.getName(), pus); + clazzToPu.put(HBaseEntityAddressUni1To1.class.getName(), pus); + clazzToPu.put(HBaseEntityAddressUni1ToM.class.getName(), pus); + clazzToPu.put(HBaseEntityAddressUniMTo1.class.getName(), pus); + clazzToPu.put(HBaseEntityPersonUniMto1.class.getName(), pus); + clazzToPu.put(HBaseEntityPersonUni1To1.class.getName(), pus); + clazzToPu.put(HBaseEntityPersonUni1ToM.class.getName(), pus); + clazzToPu.put(HBaseEntityAddressUni1To1PK.class.getName(), pus); + clazzToPu.put(HBaseEntityPersonUni1To1PK.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(HBaseEntitySimple.class); + EntityMetadata m1 = new EntityMetadata(HBaseEntitySuper.class); + EntityMetadata m2 = new EntityMetadata(HBaseEntityAddressUni1To1.class); + EntityMetadata m3 = new EntityMetadata(HBaseEntityAddressUni1ToM.class); + EntityMetadata m4 = new EntityMetadata(HBaseEntityAddressUniMTo1.class); + EntityMetadata m5 = new EntityMetadata(HBaseEntityPersonUniMto1.class); + EntityMetadata m6 = new EntityMetadata(HBaseEntityPersonUni1To1.class); + EntityMetadata m7 = new EntityMetadata(HBaseEntityPersonUni1ToM.class); + EntityMetadata m8 = new EntityMetadata(HBaseEntityPersonUni1To1PK.class); + EntityMetadata m9 = new EntityMetadata(HBaseEntityAddressUni1To1PK.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(HBaseEntitySimple.class, m); + processor.process(HBaseEntitySuper.class, m1); + processor.process(HBaseEntityAddressUni1To1.class, m2); + processor.process(HBaseEntityAddressUni1ToM.class, m3); + processor.process(HBaseEntityAddressUniMTo1.class, m4); + processor.process(HBaseEntityPersonUniMto1.class, m5); + processor.process(HBaseEntityPersonUni1To1.class, m6); + processor.process(HBaseEntityPersonUni1ToM.class, m7); + processor.process(HBaseEntityPersonUni1To1PK.class, m8); + processor.process(HBaseEntityAddressUni1To1PK.class, m9); + + m.setPersistenceUnit(persistenceUnit); + m1.setPersistenceUnit(persistenceUnit); + m2.setPersistenceUnit(persistenceUnit); + m3.setPersistenceUnit(persistenceUnit); + m4.setPersistenceUnit(persistenceUnit); + m5.setPersistenceUnit(persistenceUnit); + m6.setPersistenceUnit(persistenceUnit); + m7.setPersistenceUnit(persistenceUnit); + m8.setPersistenceUnit(persistenceUnit); + m9.setPersistenceUnit(persistenceUnit); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(HBaseEntitySimple.class, m); + metaModel.addEntityMetadata(HBaseEntitySuper.class, m1); + metaModel.addEntityMetadata(HBaseEntityAddressUni1To1.class, m2); + metaModel.addEntityMetadata(HBaseEntityAddressUni1ToM.class, m3); + metaModel.addEntityMetadata(HBaseEntityAddressUniMTo1.class, m4); + metaModel.addEntityMetadata(HBaseEntityPersonUniMto1.class, m5); + metaModel.addEntityMetadata(HBaseEntityPersonUni1To1.class, m6); + metaModel.addEntityMetadata(HBaseEntityPersonUni1ToM.class, m7); + metaModel.addEntityMetadata(HBaseEntityPersonUni1To1PK.class, m8); + metaModel.addEntityMetadata(HBaseEntityAddressUni1To1PK.class, m9); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + +// KunderaMetadata.INSTANCE.addClientMetadata(persistenceUnit, clientMetadata); + String[] persistenceUnits = { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + configuration.configure(); + // EntityManagerFactoryImpl impl = new + // EntityManagerFactoryImpl(puMetadata, props); + return null; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaOperationTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaOperationTest.java new file mode 100644 index 000000000..a01c9fe11 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/hbase/schemaManager/HBaseSchemaOperationTest.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.hbase.schemaManager; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.client.HBaseAdmin; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.hbase.HBaseClientFactory; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.Constants; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.configure.ClientFactoryConfiguraton; +import com.impetus.kundera.configure.SchemaConfiguration; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.processor.TableProcessor; +import com.impetus.kundera.persistence.EntityManagerFactoryImpl; + +/** + * @author Kuldeep.Kumar + * + */ +public class HBaseSchemaOperationTest +{ + private static final String HBASE_ENTITY_SIMPLE = "HbaseEntitySimple"; + + /** The configuration. */ + private static SchemaConfiguration configuration; + + /** Configure schema manager. */ + private SchemaManager schemaManager; + + private final boolean useLucene = false; + + private static HBaseAdmin admin; + + private static HBaseCli cli; + + private String persistenceUnit = "HBaseSchemaOperationTest"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + cli = new HBaseCli(); + cli.startCluster(); + if (admin == null) + { + admin = HBaseCli.utility.getHBaseAdmin(); + } + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + configuration = new SchemaConfiguration(null, "HBaseSchemaOperationTest"); + + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + cli.dropTable(HBASE_ENTITY_SIMPLE); + HBaseCli.stopCluster(); + + // admin = null; + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + // schemaManager.dropSchema(); + // HBaseCli.stopCluster(); + // admin = null; + } + + @Test + public void testCreate() throws IOException + { + getEntityManagerFactory("create"); + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + + HTableDescriptor descriptor = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor.getFamilies()); + Assert.assertEquals(1, descriptor.getFamilies().size()); + for (HColumnDescriptor columnDescriptor : descriptor.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertEquals(HBASE_ENTITY_SIMPLE, columnDescriptor.getNameAsString()); + } + + admin.disableTable(HBASE_ENTITY_SIMPLE); + admin.deleteTable(HBASE_ENTITY_SIMPLE); + Assert.assertFalse(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + } + + @Test + public void testCreatedrop() throws IOException + { + getEntityManagerFactory("create-drop"); +// schemaManager = new HBaseSchemaManager(HBaseClientFactory.class.getName(), null); +// schemaManager.exportSchema(); + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + + HTableDescriptor descriptor = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor.getFamilies()); + Assert.assertEquals(1, descriptor.getFamilies().size()); + for (HColumnDescriptor columnDescriptor : descriptor.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertEquals(HBASE_ENTITY_SIMPLE, columnDescriptor.getNameAsString()); + } + + HBaseClientFactory clientFactory = (HBaseClientFactory) ClientResolver.getClientFactory(persistenceUnit); + clientFactory.getSchemaManager(null).dropSchema(); + Assert.assertFalse(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + } + + @Test + public void testUpdate() throws IOException + { + HTableDescriptor descriptor1 = new HTableDescriptor(HBASE_ENTITY_SIMPLE); + HColumnDescriptor columnDescriptor1 = new HColumnDescriptor("PERSON_NAME"); + descriptor1.addFamily(columnDescriptor1); + if (admin.isTableAvailable(HBASE_ENTITY_SIMPLE)) + { + admin.disableTable(HBASE_ENTITY_SIMPLE); + admin.deleteTable(HBASE_ENTITY_SIMPLE); + } + admin.createTable(descriptor1); + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + HTableDescriptor descriptor2 = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor2.getFamilies()); + Assert.assertEquals(1, descriptor2.getFamilies().size()); + for (HColumnDescriptor columnDescriptor : descriptor2.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertEquals("PERSON_NAME", columnDescriptor.getNameAsString()); + } + + getEntityManagerFactory("update"); +// schemaManager = new HBaseSchemaManager(HBaseClientFactory.class.getName(), null); +// schemaManager.exportSchema(); + + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + + HTableDescriptor descriptor = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor.getFamilies()); + Assert.assertEquals(2, descriptor.getFamilies().size()); + List columns = new ArrayList(); + columns.add(HBASE_ENTITY_SIMPLE); + columns.add("PERSON_NAME"); + for (HColumnDescriptor columnDescriptor : descriptor.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertTrue(columns.contains(columnDescriptor.getNameAsString())); + } + + if (!admin.isTableDisabled(HBASE_ENTITY_SIMPLE)) + { + admin.disableTable(HBASE_ENTITY_SIMPLE); + } + + admin.deleteTable(HBASE_ENTITY_SIMPLE); + Assert.assertFalse(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + } + + @Test + public void testValidate() throws IOException + { + HTableDescriptor descriptor1 = new HTableDescriptor(HBASE_ENTITY_SIMPLE); + HColumnDescriptor columnDescriptor1 = new HColumnDescriptor(HBASE_ENTITY_SIMPLE); + descriptor1.addFamily(columnDescriptor1); + if (admin.isTableAvailable(HBASE_ENTITY_SIMPLE)) + { + admin.disableTable(HBASE_ENTITY_SIMPLE); + admin.deleteTable(HBASE_ENTITY_SIMPLE); + } + admin.createTable(descriptor1); + + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + HTableDescriptor descriptor2 = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor2.getFamilies()); + Assert.assertEquals(1, descriptor2.getFamilies().size()); + List columns = new ArrayList(); + columns.add(HBASE_ENTITY_SIMPLE); + for (HColumnDescriptor columnDescriptor : descriptor2.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertTrue(columns.contains(columnDescriptor.getNameAsString())); + } + + getEntityManagerFactory("validate"); +// schemaManager = new HBaseSchemaManager(HBaseClientFactory.class.getName(), null); +// schemaManager.exportSchema(); + if (!admin.isTableDisabled(HBASE_ENTITY_SIMPLE)) + { + admin.disableTable(HBASE_ENTITY_SIMPLE); + } + admin.deleteTable(HBASE_ENTITY_SIMPLE); + Assert.assertFalse(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + } + + @Test + public void testValidateInValid() throws IOException + { + try + { + HTableDescriptor descriptor1 = new HTableDescriptor(HBASE_ENTITY_SIMPLE); + HColumnDescriptor columnDescriptor1 = new HColumnDescriptor(HBASE_ENTITY_SIMPLE); + descriptor1.addFamily(columnDescriptor1); + if (admin.isTableAvailable(HBASE_ENTITY_SIMPLE)) + { + admin.disableTable(HBASE_ENTITY_SIMPLE); + admin.deleteTable(HBASE_ENTITY_SIMPLE); + } + admin.createTable(descriptor1); + Assert.assertTrue(admin.isTableAvailable(HBASE_ENTITY_SIMPLE)); + HTableDescriptor descriptor2 = admin.getTableDescriptor(HBASE_ENTITY_SIMPLE.getBytes()); + Assert.assertNotNull(descriptor2.getFamilies()); + Assert.assertEquals(1, descriptor2.getFamilies().size()); + for (HColumnDescriptor columnDescriptor : descriptor2.getFamilies()) + { + Assert.assertNotNull(columnDescriptor); + Assert.assertNotNull(columnDescriptor.getNameAsString()); + Assert.assertEquals(HBASE_ENTITY_SIMPLE, columnDescriptor.getNameAsString()); + } + + getEntityManagerFactory("validate"); +// schemaManager = new HBaseSchemaManager(HBaseClientFactory.class.getName(), null); +// schemaManager.exportSchema(); + } + catch (SchemaGenerationException sgex) + { + List errors = new ArrayList(); + errors.add("column " + "AGE" + " does not exist in table " + HBASE_ENTITY_SIMPLE + ""); + errors.add("column " + "PERSON_NAME" + " does not exist in table " + HBASE_ENTITY_SIMPLE + ""); + Assert.assertTrue(errors.contains(sgex.getMessage())); + + } + } + + /** + * Gets the entity manager factory. + * + * @param useLucene + * @param property + * + * @return the entity manager factory + */ + private EntityManagerFactoryImpl getEntityManagerFactory(String property) + { + ClientMetadata clientMetadata = new ClientMetadata(); + Map props = new HashMap(); + + props.put(Constants.PERSISTENCE_UNIT_NAME, persistenceUnit); + props.put(PersistenceProperties.KUNDERA_CLIENT_FACTORY, HBaseClientFactory.class.getName()); + props.put(PersistenceProperties.KUNDERA_NODES, "localhost"); + props.put(PersistenceProperties.KUNDERA_PORT, "2181"); + props.put(PersistenceProperties.KUNDERA_KEYSPACE, "KunderaHbaseTests"); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, property); + if (useLucene) + { + props.put(PersistenceProperties.KUNDERA_INDEX_HOME_DIR, "/home/impadmin/lucene"); + + clientMetadata.setLuceneIndexDir("/home/impadmin/lucene"); + } + else + { + + clientMetadata.setLuceneIndexDir(null); + } + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + // appMetadata = null; + PersistenceUnitMetadata puMetadata = new PersistenceUnitMetadata(); + puMetadata.setPersistenceUnitName(persistenceUnit); + Properties p = new Properties(); + p.putAll(props); + puMetadata.setProperties(p); + Map metadata = new HashMap(); + metadata.put(persistenceUnit, null); + metadata.put(persistenceUnit, puMetadata); + appMetadata.addPersistenceUnitMetadata(metadata); + + Map> clazzToPu = new HashMap>(); + + List pus = new ArrayList(); + pus.add(persistenceUnit); + clazzToPu.put(HBaseEntitySimple.class.getName(), pus); + + appMetadata.setClazzToPuMap(clazzToPu); + + EntityMetadata m = new EntityMetadata(HBaseEntitySimple.class); + + TableProcessor processor = new TableProcessor(null); + processor.process(HBaseEntitySimple.class, m); + + m.setPersistenceUnit(persistenceUnit); + + MetamodelImpl metaModel = new MetamodelImpl(); + metaModel.addEntityMetadata(HBaseEntitySimple.class, m); + + appMetadata.getMetamodelMap().put(persistenceUnit, metaModel); + + metaModel.assignManagedTypes(appMetadata.getMetaModelBuilder(persistenceUnit).getManagedTypes()); + metaModel.assignEmbeddables(appMetadata.getMetaModelBuilder(persistenceUnit).getEmbeddables()); + metaModel.assignMappedSuperClass(appMetadata.getMetaModelBuilder(persistenceUnit).getMappedSuperClassTypes()); + +// KunderaMetadata.INSTANCE.addClientMetadata(persistenceUnit, clientMetadata); + + // String[] persistenceUnits = { persistenceUnit }; + new ClientFactoryConfiguraton(null, persistenceUnit).configure(); + configuration.configure(); + // new ClientFactoryConfiguraton(null, persistenceUnits).configure(); + + return null; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/query/ResultIteratorTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/query/ResultIteratorTest.java new file mode 100644 index 000000000..d9a9e6cb0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/query/ResultIteratorTest.java @@ -0,0 +1,217 @@ +/** + * Copyright 2013 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.query; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.hbase.crud.BaseTest; +import com.impetus.client.hbase.crud.PersonHBase; +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.query.IResultIterator; +import com.impetus.kundera.query.Query; + +/** + * @author vivek.mishra junit for {@link IResultIterator}. + */ +public class ResultIteratorTest extends BaseTest +{ + /** The emf. */ + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + private HBaseCli cli = new HBaseCli(); + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + cli.startCluster(); + emf = Persistence.createEntityManagerFactory("hbaseTest"); + em = emf.createEntityManager(); + } + + @Test + public void testScrollViaCQL2() throws Exception + { + onScroll(); + } + + @Test + public void testCQL2ScrollAssociation() throws Exception + { + assertOnTokenScroll(); + } + + private void assertOnTokenScroll() + { + Token token1 = new Token(); + token1.setId("tokenId1"); + token1.setTokenName("tokenName1"); + TokenClient client = new TokenClient(); + client.setClientName("tokenClient1"); + client.setId("tokenClientId"); + token1.setClient(client); + + Token token2 = new Token(); + token2.setId("tokenId2"); + token2.setTokenName("tokenName2"); + token2.setClient(client); + em.persist(token1); + em.persist(token2); + + String queryWithoutClause = "Select t from Token t"; + assertOnTokenScroll(queryWithoutClause, 2); + + String queryWithClause = "Select t from Token t where t.tokenName='tokenName1'"; + + assertOnTokenScroll(queryWithClause, 1); + + // TODO:: Need to discuss with KK, this should be working with token + // support. Special scenario. + String queryWithIdClause = "Select t from Token t where t.id = 'tokenId1'"; + // + assertOnTokenScroll(queryWithIdClause, 1); + + } + + private void assertOnTokenScroll(String queryClause, int expected) + { + Query query = (Query) em.createQuery(queryClause, Token.class); + + int count = 0; + Iterator tokens = query.iterate(); + while (tokens.hasNext()) + { + Token token = tokens.next(); + Assert.assertNotNull(token); + Assert.assertNotNull(token.getClient()); + Assert.assertEquals(2, token.getClient().getTokens().size()); + count++; + } + + Assert.assertTrue(count > 0); + Assert.assertTrue(count == expected); + } + + private void onScroll() + { + Object p1 = prepareHbaseInstance("1", 10); + Object p2 = prepareHbaseInstance("2", 20); + Object p3 = prepareHbaseInstance("3", 15); + + em.persist(p1); + em.persist(p2); + em.persist(p3); + + em.flush(); + em.clear(); + final String queryWithoutClause = "Select p from PersonHBase p"; + + assertOnScroll(queryWithoutClause, 3); + + final String queryWithClause = "Select p from PersonHBase p where p.personName = vivek"; + + assertOnScroll(queryWithClause, 3); + + final String queryWithAndClause = "Select p from PersonHBase p where p.personName = vivek and p.age = 15"; + + assertOnScroll(queryWithAndClause, 1); + + final String queryWithLTClause = "Select p from PersonHBase p where p.personName = vivek and p.age < 15"; + + assertOnScroll(queryWithLTClause, 1); + + final String queryWithGTClause = "Select p from PersonHBase p where p.personName = vivek and p.age >= 15"; + + assertOnScroll(queryWithGTClause, 2); + + final String queryWithLTGTClause = "Select p from PersonHBase p where p.personName = vivek and p.age > 10 and p.age < 20"; + + assertOnScroll(queryWithLTGTClause, 1); + + final String queryWithLTGTEClause = "Select p from PersonHBase p where p.personName = vivek and p.age >= 10 and p.age < 20"; + + assertOnScroll(queryWithLTGTEClause, 2); + + String queryWithIdClause = "Select p from PersonHBase p where p.personId = '2' "; + assertOnScroll(queryWithIdClause, 1); + } + + private void assertOnScroll(final String queryWithoutClause, int expectedCount) + { + Query query = (Query) em.createQuery(queryWithoutClause, PersonHBase.class); + + assertOnFetch(query, 0, expectedCount); + assertOnFetch(query, 2, expectedCount); // less records + + assertOnFetch(query, 4, expectedCount); // more fetch size than + // available in db. + assertOnFetch(query, 3, expectedCount); // more fetch size than + // available in db. + + assertOnFetch(query, null, expectedCount); // set to null; + + } + + private void assertOnFetch(Query query, Integer fetchSize, int available) + { + query.setFetchSize(fetchSize); + int counter = 0; + Iterator iter = query.iterate(); + + while (iter.hasNext()) + { + Assert.assertNotNull(iter.next()); + counter++; + } + + Assert.assertEquals(counter, fetchSize == null || available < fetchSize ? available : fetchSize); + try + { + iter.next(); + Assert.fail(); + } + catch (NoSuchElementException nsex) + { + Assert.assertNotNull(nsex.getMessage()); + } + } + + @After + public void tearDown() + { + cli.stopCluster("PERSON_HBASE"); + } +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/query/Token.java b/src/kundera-hbase/src/test/java/com/impetus/client/query/Token.java new file mode 100644 index 000000000..73ff21c20 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/query/Token.java @@ -0,0 +1,61 @@ +package com.impetus.client.query; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "tokens", schema = "KunderaExamples@hbaseTest") +public class Token +{ + @Id + @Column(name = "token_id") + private String id; + + @ManyToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "client_id") + private TokenClient client; + + @Column + private String tokenName; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public TokenClient getClient() + { + return client; + } + + public void setClient(TokenClient client) + { + this.client = client; + } + + public String getTokenName() + { + return tokenName; + } + + public void setTokenName(String tokenName) + { + this.tokenName = tokenName; + } + + +} \ No newline at end of file diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/query/TokenClient.java b/src/kundera-hbase/src/test/java/com/impetus/client/query/TokenClient.java new file mode 100644 index 000000000..14ffd2bf7 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/query/TokenClient.java @@ -0,0 +1,57 @@ +package com.impetus.client.query; + +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +@Entity +@Table(name = "client", schema = "KunderaExamples@hbaseTest") +public class TokenClient +{ + + @Id + @Column(name = "client_id") + private String id; + + @Column(name = "client_name") + private String clientName; + + @OneToMany(mappedBy = "client", fetch = FetchType.LAZY) + private Set tokens; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getClientName() + { + return clientName; + } + + public void setClientName(String clientName) + { + this.clientName = clientName; + } + + public Set getTokens() + { + return tokens; + } + + public void setTokens(Set tokens) + { + this.tokens = tokens; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwibaseTest.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwibaseTest.java new file mode 100644 index 000000000..7ad5dbfec --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwibaseTest.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import org.junit.Test; + +import com.impetus.client.hbase.junits.HBaseCli; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * Test case for Twitter like application on HBase + * + * @author amresh.singh + */ +public class TwibaseTest extends TwitterTestBaseHbase +{ + + HBaseCli cli = new HBaseCli(); + + @Override + protected void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + setUpInternal("twibaseTest"); + } + + /** + * Test on execute. + */ + @Test + public void testOnExecute() + { + executeTestSuite(); + } + + @Override + protected void tearDown() throws Exception + { + tearDownInternal(); + } + + @Override + void startServer() + { + cli.startCluster(); + } + + @Override + void stopServer() + { + cli.stopCluster(); + } + + @Override + void createSchema() + { + if (AUTO_MANAGE_SCHEMA) + {/* + * cli.createTable("USER"); cli.addColumnFamily("USER", + * "PREFERENCE_ID"); cli.addColumnFamily("USER", "FRIEND_ID"); + * cli.addColumnFamily("USER", "FOLLOWER_ID"); + * cli.addColumnFamily("USER", "personalDetail"); + * + * cli.createTable("PREFERENCE"); cli.addColumnFamily("PREFERENCE", + * "WEBSITE_THEME"); cli.addColumnFamily("PREFERENCE", + * "PRIVACY_LEVEL"); + * + * cli.createTable("EXTERNAL_LINK"); + * cli.addColumnFamily("EXTERNAL_LINK", "LINK_TYPE"); + * cli.addColumnFamily("EXTERNAL_LINK", "USER_ID"); + * cli.addColumnFamily("EXTERNAL_LINK", "LINK_ADDRESS"); + */ + } + } + + @Override + void deleteSchema() + { + cli.dropTable("EXTERNAL_LINK"); + cli.dropTable("PREFERENCE"); + cli.dropTable("USER_HBASE"); + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwitterTestBaseHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwitterTestBaseHbase.java new file mode 100644 index 000000000..f4755cd99 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/TwitterTestBaseHbase.java @@ -0,0 +1,479 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.impetus.client.twitter.dao.TwitterHbase; +import com.impetus.client.twitter.dao.TwitterServiceHbase; +import com.impetus.client.twitter.entities.ExternalLinkHBase; +import com.impetus.client.twitter.entities.PersonalDetailHbase; +import com.impetus.client.twitter.entities.PreferenceHBase; +import com.impetus.client.twitter.entities.TweetHbase; +import com.impetus.client.twitter.entities.UserHBase; +import com.impetus.kundera.utils.LuceneCleanupUtilities; + +/** + * Test case for MongoDB. + * + * @author amresh.singh + */ +public abstract class TwitterTestBaseHbase extends TestCase +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + /** The user id1. */ + String userId1; + + /** The user id2. */ + String userId2; + + /** The twitter. */ + protected TwitterHbase twitter; + + private String persistenceUnitName; + + /** + * Sets the up internal. + * + * @param persistenceUnitName + * the new up internal + * @throws Exception + * the exception + */ + protected void setUpInternal(String persistenceUnitName) throws Exception + { + this.persistenceUnitName = persistenceUnitName; + userId1 = "0001"; + userId2 = "0002"; + + // Start Cassandra Server + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + twitter = new TwitterServiceHbase(persistenceUnitName); + + // Create Schema + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + /** + * Tear down internal. + * + * @throws Exception + * the exception + */ + protected void tearDownInternal() throws Exception + { + if (twitter != null) + { + twitter.close(); + } + + if (AUTO_MANAGE_SCHEMA) + { + deleteSchema(); + } + + // Stop Server + if (RUN_IN_EMBEDDED_MODE) + { + stopServer(); + } + + LuceneCleanupUtilities.cleanLuceneDirectory(persistenceUnitName); + } + + /** + * Execute suite. + */ + protected void executeTestSuite() + { + // Insert, Find and Update + addAllUserInfo(); + getUserById(); + updateUser(); + + // Queries + getAllUsers(); + getAllTweets(); + + // Remove Users + removeUser(); + + } + + protected void addAllUserInfo() + { + UserHBase user1 = buildUser1(); + UserHBase user2 = buildUser2(); + + twitter.createEntityManager(); + twitter.addUser(user1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(user2); + twitter.closeEntityManager(); + } + + protected void getUserById() + { + twitter.createEntityManager(); + UserHBase user1 = twitter.findUserById(userId1); + assertUser1(user1); + + UserHBase user2 = twitter.findUserById(userId2); + assertUser2(user2); + + } + + protected void updateUser() + { + twitter.createEntityManager(); + UserHBase user1 = twitter.findUserById(userId1); + assertUser1(user1); + + user1.setPersonalDetail(new PersonalDetailHbase("Vivek", "unknown", "Married")); + user1.addTweet(new TweetHbase("My Third Tweet", "iPhone")); + twitter.mergeUser(user1); + + UserHBase user1AfterMerge = twitter.findUserById(userId1); + + assertUpdatedUser1(user1AfterMerge); + + twitter.closeEntityManager(); + } + + protected void removeUser() + { + twitter.createEntityManager(); + UserHBase user1 = twitter.findUserById(userId1); + assertUpdatedUser1(user1); + + twitter.removeUser(user1); + + UserHBase user1AfterRemoval = twitter.findUserById(userId1); + Assert.assertNull(user1AfterRemoval); + + twitter.closeEntityManager(); + + } + + protected void getAllUsers() + { + twitter.createEntityManager(); + List users = twitter.getAllUsers(); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertEquals(2, users.size()); + + for (UserHBase u : users) + { + Assert.assertNotNull(u); + if (u.getUserId().equals(userId1)) + { + assertUpdatedUser1(u); + } + else if (u.getUserId().equals(userId2)) + { + assertUser2(u); + } + } + twitter.closeEntityManager(); + } + + /** + * Adds the users. + */ + protected void addUsers() + { + twitter.createEntityManager(); + twitter.addUser(userId1, "Amresh", "password1", "married"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(userId2, "Saurabh", "password2", "single"); + twitter.closeEntityManager(); + } + + /** + * Save preference. + */ + protected void savePreference() + { + twitter.createEntityManager(); + twitter.savePreference(userId1, new PreferenceHBase("P1", "Motif", "2")); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.savePreference(userId2, new PreferenceHBase("P2", "High Contrast", "3")); + twitter.closeEntityManager(); + } + + /** + * Adds the external links. + */ + protected void addExternalLinks() + { + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L1", "Facebook", "http://facebook.com/coolnerd"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L2", "LinkedIn", "http://linkedin.com/in/devilmate"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L3", "GooglePlus", "http://plus.google.com/inviteme"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry"); + twitter.closeEntityManager(); + } + + /** + * Adds the tweets. + */ + protected void addTweets() + { + twitter.createEntityManager(); + twitter.addTweet(userId1, "Here is my first tweet", "Web"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId1, "Second Tweet from me", "Mobile"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Saurabh tweets for the first time", "Phone"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Another tweet from Saurabh", "text"); + twitter.closeEntityManager(); + } + + /** + * User1 follows user2. + */ + protected void user1FollowsUser2() + { + twitter.createEntityManager(); + twitter.startFollowing(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * User1 adds user2 as follower. + */ + protected void user1AddsUser2AsFollower() + { + twitter.createEntityManager(); + twitter.addFollower(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * Gets the all tweets. + * + * @return the all tweets + */ + protected void getAllTweets() + { + twitter.createEntityManager(); + + List tweetsUser1 = twitter.getAllTweets(userId1); + List tweetsUser2 = twitter.getAllTweets(userId2); + + twitter.closeEntityManager(); + + assertNotNull(tweetsUser1); + assertNotNull(tweetsUser2); + + assertFalse(tweetsUser1.isEmpty()); + assertFalse(tweetsUser2.isEmpty()); + + assertEquals(3, tweetsUser1.size()); + assertEquals(2, tweetsUser2.size()); + } + + /** + * Gets the tweets by body. + * + * @return the tweets by body + */ + public void getTweetsByBody() + { + twitter.createEntityManager(); + List user1Tweet = twitter.findTweetByBody("Here"); + List user2Tweet = twitter.findTweetByBody("Saurabh"); + + twitter.closeEntityManager(); + + assertNotNull(user1Tweet); + assertNotNull(user2Tweet); + assertEquals(1, user1Tweet.size()); + assertEquals(1, user2Tweet.size()); + } + + /** + * Gets the tweet by device. + * + * @return the tweet by device + */ + public void getTweetsByDevice() + { + twitter.createEntityManager(); + List webTweets = twitter.findTweetByDevice("Web"); + List mobileTweets = twitter.findTweetByDevice("Mobile"); + + twitter.closeEntityManager(); + + assertNotNull(webTweets); + assertNotNull(mobileTweets); + assertEquals(1, webTweets.size()); + assertEquals(1, mobileTweets.size()); + + } + + /** + * Gets the all followers. + * + * @return the all followers + */ + protected void getAllFollowers() + { + twitter.createEntityManager(); + List follower1 = twitter.getFollowers(userId1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List follower2 = twitter.getFollowers(userId2); + twitter.closeEntityManager(); + + assertNull(follower1); + assertNotNull(follower2); + } + + /** + * @return + */ + private UserHBase buildUser1() + { + UserHBase user1 = new UserHBase(userId1, "Amresh", "password1", "married"); + + user1.setPreference(new PreferenceHBase("P1", "Motif", "2")); + + user1.addExternalLink(new ExternalLinkHBase("L1", "Facebook", "http://facebook.com/coolnerd")); + user1.addExternalLink(new ExternalLinkHBase("L2", "LinkedIn", "http://linkedin.com/in/devilmate")); + + user1.addTweet(new TweetHbase("Here is my first tweet", "Web")); + user1.addTweet(new TweetHbase("Second Tweet from me", "Mobile")); + return user1; + } + + /** + * @return + */ + private UserHBase buildUser2() + { + UserHBase user2 = new UserHBase(userId2, "Saurabh", "password2", "single"); + + user2.setPreference(new PreferenceHBase("P2", "High Contrast", "3")); + + user2.addExternalLink(new ExternalLinkHBase("L3", "GooglePlus", "http://plus.google.com/inviteme")); + user2.addExternalLink(new ExternalLinkHBase("L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry")); + + user2.addTweet(new TweetHbase("Saurabh tweets for the first time", "Phone")); + user2.addTweet(new TweetHbase("Another tweet from Saurabh", "text")); + return user2; + } + + private void assertUser1(UserHBase user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Amresh", user1.getPersonalDetail().getName()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(2, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + private void assertUser2(UserHBase user2) + { + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + Assert.assertNotNull(user2.getPersonalDetail()); + Assert.assertEquals("Saurabh", user2.getPersonalDetail().getName()); + Assert.assertNotNull(user2.getPreference()); + Assert.assertEquals("3", user2.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user2.getTweets()); + Assert.assertFalse(user2.getTweets().isEmpty()); + Assert.assertEquals(2, user2.getTweets().size()); + Assert.assertNotNull(user2.getExternalLinks()); + Assert.assertFalse(user2.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user2.getExternalLinks().size()); + } + + private void assertUpdatedUser1(UserHBase user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Vivek", user1.getPersonalDetail().getName()); + Assert.assertEquals("unknown", user1.getPersonalDetail().getPassword()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(3, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + abstract void startServer(); + + abstract void stopServer(); + + abstract void deleteSchema(); + + abstract void createSchema(); +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/SuperDaoHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/SuperDaoHbase.java new file mode 100644 index 000000000..526b54151 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/SuperDaoHbase.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +/** + * The Class SuperDao. + * + * @author impetus + */ +public class SuperDaoHbase +{ + + /** + * Inits the. + * + * @param persistenceUnitName + * the persistence unit name + * @return the entity manager + * @throws Exception + * the exception + */ + protected EntityManagerFactory createEntityManagerFactory(String persistenceUnitName) + { + return Persistence.createEntityManagerFactory(persistenceUnitName); + + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterHbase.java new file mode 100644 index 000000000..022418012 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterHbase.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.util.List; + +import com.impetus.client.twitter.entities.PreferenceHBase; +import com.impetus.client.twitter.entities.TweetHbase; +import com.impetus.client.twitter.entities.UserHBase; + +/** + * Single window application for Twitter application. Contains methods for + * performing CRUD operations on users and their tweets. + */ +public interface TwitterHbase +{ + + void addUser(UserHBase user); + + /** + * Registers a new user with Twitter application + * + * @param userId + * the user id + * @param name + * the name + * @param password + * the password + * @param relationshipStatus + * the relationship status + */ + void addUser(String userId, String name, String password, String relationshipStatus); + + /** + * Save preference for a given user + * + * @param userId + * the user id + * @param preference + * the preference + */ + void savePreference(String userId, PreferenceHBase preference); + + /** + * Adds an external link for the given user + * + * @param userId + * the user id + * @param linkType + * the link type + * @param linkAddress + * the link address + */ + void addExternalLink(String userId, String linkId, String linkType, String linkAddress); + + /** + * Adds a new tweet for a user + * + * @param userId + * the user id + * @param tweetBody + * the tweet body + * @param device + * the device + */ + void addTweet(String userId, String tweetBody, String device); + + /** + * Makes User whose row key is userId follow a user whose row + * key is friendUserId + * + * @param userId + * the user id + * @param friendUserId + * the friend user id + */ + void startFollowing(String userId, String friendUserId); + + /** + * Adds the follower whose row key is followerUserId to User + * whose row key is userId + * + * @param userId + * the user id + * @param followerUserId + * the follower user id + */ + void addFollower(String userId, String followerUserId); + + UserHBase findUserById(String userId); + + void removeUser(UserHBase user); + + void mergeUser(UserHBase user); + + /** + * Retrieves all tweets for a given user + * + * @param userId + * the user id + * @return the all tweets + */ + List getAllUsers(); + + List getAllTweets(String userId); + + /** + * Returns a list of followers for a given user. + * + * @param userId + * user id + * @return list of all followers. + */ + List getFollowers(String userId); + + /** + * Find tweet by tweet body. + * + * @param tweetBody + * the tweet body + * @return the list + */ + List findTweetByBody(String tweetBody); + + /** + * Find tweet by device. + * + * @param deviceName + * the device name + * @return the list + */ + List findTweetByDevice(String deviceName); + + /** + * Close. + */ + void close(); + + void createEntityManager(); + + void closeEntityManager(); + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterServiceHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterServiceHbase.java new file mode 100644 index 000000000..7088639cc --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/dao/TwitterServiceHbase.java @@ -0,0 +1,224 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Query; + +import com.impetus.client.twitter.entities.ExternalLinkHBase; +import com.impetus.client.twitter.entities.PreferenceHBase; +import com.impetus.client.twitter.entities.TweetHbase; +import com.impetus.client.twitter.entities.UserHBase; + +/** + * Data access object class for implementation of twitter. + * + * @author amresh.singh + */ +public class TwitterServiceHbase extends SuperDaoHbase implements TwitterHbase +{ + private EntityManager em; + + private EntityManagerFactory emf; + + public TwitterServiceHbase(String persistenceUnitName) + { + if (emf == null) + { + try + { + emf = createEntityManagerFactory(persistenceUnitName); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + } + + @Override + public void createEntityManager() + { + if (em == null) + { + em = emf.createEntityManager(); + } + } + + @Override + public void closeEntityManager() + { + if (em != null) + { + em.clear(); + em.close(); + em = null; + } + } + + @Override + public void close() + { + if (emf != null) + { + emf.close(); + } + } + + @Override + public void addUser(UserHBase user) + { + em.persist(user); + } + + @Override + public void addUser(String userId, String name, String password, String relationshipStatus) + { + UserHBase user = new UserHBase(userId, name, password, relationshipStatus); + em.persist(user); + + } + + @Override + public void savePreference(String userId, PreferenceHBase preference) + { + + UserHBase user = em.find(UserHBase.class, userId); + user.setPreference(preference); + em.persist(user); + } + + @Override + public void addExternalLink(String userId, String linkId, String linkType, String linkAddress) + { + UserHBase user = em.find(UserHBase.class, userId); + user.addExternalLink(new ExternalLinkHBase(linkId, linkType, linkAddress)); + + em.persist(user); + } + + @Override + public void addTweet(String userId, String tweetBody, String device) + { + UserHBase user = em.find(UserHBase.class, userId); + user.addTweet(new TweetHbase(tweetBody, device)); + em.persist(user); + } + + @Override + public void startFollowing(String userId, String friendUserId) + { + UserHBase user = em.find(UserHBase.class, userId); + UserHBase friend = em.find(UserHBase.class, friendUserId); + + user.addFriend(friend); + em.persist(user); + + friend.addFollower(user); + em.persist(friend); + } + + @Override + public void addFollower(String userId, String followerUserId) + { + UserHBase user = em.find(UserHBase.class, userId); + UserHBase follower = em.find(UserHBase.class, followerUserId); + + user.addFollower(follower); + em.persist(user); + } + + @Override + public UserHBase findUserById(String userId) + { + UserHBase user = em.find(UserHBase.class, userId); + return user; + } + + @Override + public void removeUser(UserHBase user) + { + em.remove(user); + } + + @Override + public void mergeUser(UserHBase user) + { + em.merge(user); + } + + @Override + public List getAllUsers() + { + + Query q = em.createQuery("select u from UserHBase u"); + + List users = q.getResultList(); + + return users; + } + + @Override + public List getAllTweets(String userId) + { + Query q = em.createQuery("select u from UserHBase u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + else + { + return users.get(0).getTweets(); + } + } + + @Override + public List getFollowers(String userId) + { + Query q = em.createQuery("select u from UserHBase u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + return users.get(0).getFollowers(); + } + + @Override + public List findTweetByBody(String tweetBody) + { + Query q = em.createQuery("select u.tweet_body from UserHBase u where u.tweet_body like :body"); + q.setParameter("body", tweetBody); + List tweets = q.getResultList(); + return tweets; + } + + @Override + public List findTweetByDevice(String deviceName) + { + Query q = em.createQuery("select u.tweeted_from from UserHBase u where u.tweeted_from like :device"); + q.setParameter("device", deviceName); + List tweets = q.getResultList(); + return tweets; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/ExternalLinkHBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/ExternalLinkHBase.java new file mode 100644 index 000000000..53128ce4d --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/ExternalLinkHBase.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for user's External link details + * + * @author amresh.singh + */ + +@Entity +@Table(name = "EXTERNAL_LINK", schema = "KunderaExamples@twibaseTest") +public class ExternalLinkHBase +{ + + @Id + @Column(name = "EXT_LINK_ID") + private String extLinkId; + + @Column(name = "LINK_TYPE") + private String linkType; + + @Column(name = "LINK_ADDRESS") + private String linkAddress; + + public ExternalLinkHBase() + { + } + + public ExternalLinkHBase(String extLinkId, String type, String address) + { + this.extLinkId = extLinkId; + this.linkType = type; + this.linkAddress = address; + } + + /** + * @return the extLinkId + */ + public String getExtLinkId() + { + return extLinkId; + } + + /** + * @param extLinkId + * the extLinkId to set + */ + public void setExtLinkId(String extLinkId) + { + this.extLinkId = extLinkId; + } + + /** + * @return the linkType + */ + public String getLinkType() + { + return linkType; + } + + /** + * @param linkType + * the linkType to set + */ + public void setLinkType(String linkType) + { + this.linkType = linkType; + } + + /** + * @return the linkAddress + */ + public String getLinkAddress() + { + return linkAddress; + } + + /** + * @param linkAddress + * the linkAddress to set + */ + public void setLinkAddress(String linkAddress) + { + this.linkAddress = linkAddress; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PersonalDetailHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PersonalDetailHbase.java new file mode 100644 index 000000000..0b2296e39 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PersonalDetailHbase.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsHbase; + +/** + * Entity class for user's personal details + * + * @author amresh.singh + */ + +@Embeddable +public class PersonalDetailHbase +{ + @Column(name = "personal_detail_id") + private String personalDetailId; + + @Column(name = "name") + private String name; + + @Column(name = "password") + private String password; + + @Column(name = "rel_status") + private String relationshipStatus; + + public PersonalDetailHbase() + { + + } + + public PersonalDetailHbase(String name, String password, String relationshipStatus) + { + setPersonalDetailId(ExampleUtilsHbase.getUniqueId()); + setName(name); + setPassword(password); + setRelationshipStatus(relationshipStatus); + } + + /** + * @return the personalDetailId + */ + public String getPersonalDetailId() + { + return personalDetailId; + } + + /** + * @param personalDetailId + * the personalDetailId to set + */ + public void setPersonalDetailId(String personalDetailId) + { + this.personalDetailId = personalDetailId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the password + */ + public String getPassword() + { + return password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * @return the relationshipStatus + */ + public String getRelationshipStatus() + { + return relationshipStatus; + } + + /** + * @param relationshipStatus + * the relationshipStatus to set + */ + public void setRelationshipStatus(String relationshipStatus) + { + this.relationshipStatus = relationshipStatus; + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PreferenceHBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PreferenceHBase.java new file mode 100644 index 000000000..ae687272e --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/PreferenceHBase.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for User Preferences + * + * @author amresh.singh + */ + +@Entity +@Table(name = "PREFERENCE", schema = "KunderaExamples@twibaseTest") +public class PreferenceHBase +{ + @Id + @Column(name = "PREFERENCE_ID") + String preferenceId; + + @Column(name = "WEBSITE_THEME") + String websiteTheme; + + @Column(name = "PRIVACY_LEVEL") + String privacyLevel; // 1, 2, 3 + + public PreferenceHBase() + { + + } + + public PreferenceHBase(String preferenceId, String theme, String privacyLevel) + { + this.preferenceId = preferenceId; + this.websiteTheme = theme; + this.privacyLevel = privacyLevel; + } + + /** + * @return the preferenceId + */ + public String getPreferenceId() + { + return preferenceId; + } + + /** + * @param preferenceId + * the preferenceId to set + */ + public void setPreferenceId(String preferenceId) + { + this.preferenceId = preferenceId; + } + + /** + * @return the websiteTheme + */ + public String getWebsiteTheme() + { + return websiteTheme; + } + + /** + * @param websiteTheme + * the websiteTheme to set + */ + public void setWebsiteTheme(String websiteTheme) + { + this.websiteTheme = websiteTheme; + } + + /** + * @return the privacyLevel + */ + public String getPrivacyLevel() + { + return privacyLevel; + } + + /** + * @param privacyLevel + * the privacyLevel to set + */ + public void setPrivacyLevel(String privacyLevel) + { + this.privacyLevel = privacyLevel; + } +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/TweetHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/TweetHbase.java new file mode 100644 index 000000000..caffe323a --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/TweetHbase.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsHbase; + +/** + * Class for Tweets + * + * @author amresh.singh + */ + +@Embeddable +public class TweetHbase +{ + + @Column(name = "tweet_id") + private String tweetId; + + @Column(name = "tweet_body") + private String body; + + @Column(name = "tweeted_from") + private String device; + + // private long timestamp; + + public TweetHbase(String body, String device) + { + this.tweetId = ExampleUtilsHbase.getUniqueId(); + this.body = body; + this.device = device; + // this.timestamp = ExampleUtils.getCurrentTimestamp(); + } + + public TweetHbase() + { + + } + + /** + * @return the tweetId + */ + public String getTweetId() + { + return tweetId; + } + + /** + * @param tweetId + * the tweetId to set + */ + public void setTweetId(String tweetId) + { + this.tweetId = tweetId; + } + + /** + * @return the body + */ + public String getBody() + { + return body; + } + + /** + * @param body + * the body to set + */ + public void setBody(String body) + { + this.body = body; + } + + /** + * @return the device + */ + public String getDevice() + { + return device; + } + + /** + * @param device + * the device to set + */ + public void setDevice(String device) + { + this.device = device; + } + + /* *//** + * @return the timestamp + */ + /* + * public long getTimestamp() { return timestamp; } + *//** + * @param timestamp + * the timestamp to set + */ + /* + * public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + */ +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/UserHBase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/UserHBase.java new file mode 100644 index 000000000..04c58b3b0 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/entities/UserHBase.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * @author impetus + * + */ +@Entity +@Table(name = "USER_HBASE", schema = "KunderaExamples@twibaseTest") +public class UserHBase +{ + + @Id + @Column(name = "USER_ID") + private String userId; + + // Embedded object, will persist co-located + @Embedded + private PersonalDetailHbase personalDetail; + + // Element collection, will persist co-located + @ElementCollection + @CollectionTable(name = "tweeted") + private List tweets; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FRIEND_ID") + private List friends; // List of users whom I follow + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FOLLOWER_ID") + private List followers; // List of users who are following me + + // One-to-one, will be persisted separately + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "PREFERENCE_ID") + private PreferenceHBase preference; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "USER_ID") + private Set externalLinks; + + public UserHBase() + { + + } + + public UserHBase(String userId, String name, String password, String relationshipStatus) + { + PersonalDetailHbase pd = new PersonalDetailHbase(name, password, relationshipStatus); + setUserId(userId); + setPersonalDetail(pd); + } + + /** + * @return the userId + */ + public String getUserId() + { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(String userId) + { + this.userId = userId; + } + + /** + * @return the personalDetail + */ + public PersonalDetailHbase getPersonalDetail() + { + return personalDetail; + } + + /** + * @param personalDetail + * the personalDetail to set + */ + public void setPersonalDetail(PersonalDetailHbase personalDetail) + { + this.personalDetail = personalDetail; + } + + /** + * @return the tweets + */ + public List getTweets() + { + return tweets; + } + + /** + * @param tweets + * the tweets to set + */ + public void addTweet(TweetHbase tweet) + { + if (this.tweets == null || this.tweets.isEmpty()) + { + this.tweets = new ArrayList(); + } + this.tweets.add(tweet); + } + + /** + * @return the preference + */ + public PreferenceHBase getPreference() + { + return preference; + } + + /** + * @param preference + * the preference to set + */ + public void setPreference(PreferenceHBase preference) + { + this.preference = preference; + } + + /** + * @return the externalLinks + */ + public Set getExternalLinks() + { + return externalLinks; + } + + /** + * @param imDetails + * the imDetails to set + */ + public void addExternalLink(ExternalLinkHBase externalLink) + { + if (this.externalLinks == null || this.externalLinks.isEmpty()) + { + this.externalLinks = new HashSet(); + } + + this.externalLinks.add(externalLink); + } + + /** + * @return the friends + */ + public List getFriends() + { + return friends; + } + + /** + * @param friends + * the friends to set + */ + public void addFriend(UserHBase friend) + { + if (this.friends == null || this.friends.isEmpty()) + { + this.friends = new ArrayList(); + } + this.friends.add(friend); + } + + /** + * @return the followers + */ + public List getFollowers() + { + return followers; + } + + /** + * @param followers + * the followers to set + */ + public void addFollower(UserHBase follower) + { + if (this.followers == null || this.followers.isEmpty()) + { + this.followers = new ArrayList(); + } + + this.followers.add(follower); + } + +} diff --git a/src/kundera-hbase/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsHbase.java b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsHbase.java new file mode 100644 index 000000000..589cc9a64 --- /dev/null +++ b/src/kundera-hbase/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsHbase.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.utils; + +import java.util.Date; +import java.util.UUID; + +/** + * Class for utility methods + * + * @author amresh.singh + */ +public class ExampleUtilsHbase +{ + public static String getUniqueId() + { + return UUID.randomUUID().toString(); + } + + public static long getCurrentTimestamp() + { + return new Date().getTime(); + } + +} diff --git a/src/kundera-hbase/src/test/resources/META-INF/persistence.xml b/src/kundera-hbase/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..2fa1d571b --- /dev/null +++ b/src/kundera-hbase/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,139 @@ + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + diff --git a/src/kundera-hbase/src/test/resources/META-INF/persistence_2_0.xsd b/src/kundera-hbase/src/test/resources/META-INF/persistence_2_0.xsd new file mode 100644 index 000000000..d94620392 --- /dev/null +++ b/src/kundera-hbase/src/test/resources/META-INF/persistence_2_0.xsd @@ -0,0 +1,354 @@ + + + + + + + @(#)persistence_2_0.xsd 1.0 October 1 2009 + + + + + + + Copyright (c) 2008, 2009 Sun Microsystems. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + which accompanies this distribution. + The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + Contributors: + Linda DeMichiel - Java Persistence 2.0, Version 2.0 (October 1, 2009) + Specification available from http://jcp.org/en/jsr/detail?id=317 + + + + + + + ... + + + ]]> + + + + + + + + + + + + + + + + + + + + + + Configuration of a persistence unit. + + + + + + + + + + + + Description of this persistence unit. + + + + + + + + + + + + Provider class that supplies EntityManagers for this + persistence unit. + + + + + + + + + + + + The container-specific name of the JTA datasource to use. + + + + + + + + + + + + The container-specific name of a non-JTA datasource to use. + + + + + + + + + + + + File containing mapping information. Loaded as a resource + by the persistence provider. + + + + + + + + + + + + Jar file that is to be scanned for managed classes. + + + + + + + + + + + + Managed class to be included in the persistence unit and + to scan for annotations. It should be annotated + with either @Entity, @Embeddable or @MappedSuperclass. + + + + + + + + + + + + When set to true then only listed classes and jars will + be scanned for persistent classes, otherwise the + enclosing jar or directory will also be scanned. + Not applicable to Java SE persistence units. + + + + + + + + + + + + Defines whether caching is enabled for the + persistence unit if caching is supported by the + persistence provider. When set to ALL, all entities + will be cached. When set to NONE, no entities will + be cached. When set to ENABLE_SELECTIVE, only entities + specified as cacheable will be cached. When set to + DISABLE_SELECTIVE, entities specified as not cacheable + will not be cached. When not specified or when set to + UNSPECIFIED, provider defaults may apply. + + + + + + + + + + + + The validation mode to be used for the persistence unit. + + + + + + + + + + + + + A list of standard and vendor-specific properties + and hints. + + + + + + + + + A name-value pair. + + + + + + + + + + + + + + + + + + + + Name used in code to reference this persistence unit. + + + + + + + + + + + + Type of transactions used by EntityManagers from this + persistence unit. + + + + + + + + + + + + + + + + + + + public enum PersistenceUnitTransactionType {JTA, RESOURCE_LOCAL}; + + + + + + + + + + + + + + + + public enum SharedCacheMode { ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE, UNSPECIFIED}; + + + + + + + + + + + + + + + + + + + public enum ValidationMode { AUTO, CALLBACK, NONE}; + + + + + + + + + + + diff --git a/src/kundera-hbase/src/test/resources/kundera-hbase.properties b/src/kundera-hbase/src/test/resources/kundera-hbase.properties new file mode 100644 index 000000000..85225fb54 --- /dev/null +++ b/src/kundera-hbase/src/test/resources/kundera-hbase.properties @@ -0,0 +1,3 @@ +zookeeper.port = 2181 +zookeeper.host = localhost +cf.defs=HBaseEntity|GZ|123456|5|2 \ No newline at end of file diff --git a/src/kundera-hbase/src/test/resources/log4j.properties b/src/kundera-hbase/src/test/resources/log4j.properties new file mode 100644 index 000000000..e656bb981 --- /dev/null +++ b/src/kundera-hbase/src/test/resources/log4j.properties @@ -0,0 +1,15 @@ +log4j.rootLogger=ERROR, DRFA, CONSOLE + +### direct log messages to stdout ### +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.File=${user.home}/kundera.log +# Rollover at midnight +log4j.appender.DRFA.DatePattern=.yyyy-MM-dd +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +# Pattern format: Date LogLevel LoggerName LogMessage +log4j.appender.DRFA.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n + + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n diff --git a/src/kundera-mongo/pom.xml b/src/kundera-mongo/pom.xml new file mode 100644 index 000000000..6bf6fe35e --- /dev/null +++ b/src/kundera-mongo/pom.xml @@ -0,0 +1,99 @@ + + 4.0.0 + + + com.impetus + kundera + 2.7-SNAPSHOT + + com.impetus.client + kundera-mongo + jar + kundera-mongo + http://maven.apache.org + + + + + com.impetus.core + kundera-core + ${project.version} + + + com.impetus.core + kundera-core + ${project.version} + test-jar + test + + + org.mongodb + mongo-java-driver + 2.9.1 + + + junit + junit + 4.8.2 + test + + + + + org.databene + contiperf + 2.2.0 + test + + + + + + + + + + maven-assembly-plugin + 2.2.1 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + + diff --git a/src/kundera-mongo/src/main/java/META-INF/MANIFEST.MF b/src/kundera-mongo/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 000000000..5e9495128 --- /dev/null +++ b/src/kundera-mongo/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/DocumentObjectMapper.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/DocumentObjectMapper.java new file mode 100644 index 000000000..e183c0454 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/DocumentObjectMapper.java @@ -0,0 +1,323 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.utils.MongoDBUtils; +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.metadata.model.attributes.AttributeType; +import com.impetus.kundera.persistence.EntityReaderException; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.property.accessor.EnumAccessor; +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.BasicDBObjectBuilder; +import com.mongodb.DBObject; + +/** + * Provides functionality for mapping between MongoDB documents and POJOs. + * Contains utility methods for converting one form into another. + * + * @author amresh.singh + */ +public class DocumentObjectMapper +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(DocumentObjectMapper.class); + + /** + * Creates a MongoDB document object wrt a given Java object. columns in the + * document correspond Columns provided as List. + * + * @param obj + * the obj + * @param columns + * the columns + * @return the document from object + * @throws PropertyAccessException + * the property access exception + */ + static BasicDBObject getDocumentFromObject(Object obj, Set columns) throws PropertyAccessException + { + BasicDBObject dBObj = new BasicDBObject(); + + for (Attribute column : columns) + { + extractFieldValue(obj, dBObj, column); + } + return dBObj; + } + + /** + * Creates a MongoDB document list from a given java collection. columns in + * the document correspond Columns provided as List. + * + * @param coll + * the coll + * @param columns + * the columns + * @return the document list from collection + * @throws PropertyAccessException + * the property access exception + */ + static BasicDBObject[] getDocumentListFromCollection(Collection coll, Set columns) + throws PropertyAccessException + { + BasicDBObject[] dBObjects = new BasicDBObject[coll.size()]; + int count = 0; + for (Object o : coll) + { + dBObjects[count] = getDocumentFromObject(o, columns); + count++; + } + return dBObjects; + } + + /** + * Creates an instance of clazz and populates fields fetched + * from MongoDB document object. Field names are determined from + * columns + * + * @param documentObj + * the document obj + * @param clazz + * the clazz + * @param columns + * the columns + * @return the object from document + */ + static Object getObjectFromDocument(BasicDBObject documentObj, Class clazz, Set columns) + { + try + { + Object obj = clazz.newInstance(); + for (Attribute column : columns) + { + setFieldValue(documentObj, obj, column); + } + return obj; + } + catch (InstantiationException e) + { + throw new PersistenceException(e); + } + catch (IllegalAccessException e) + { + throw new PersistenceException(e); + } + } + + /** + * Setter for column value, by default converted from string value, in case + * of map it is automatically converted into map using BasicDBObject. + * + * @param document + * mongo document + * @param entityObject + * searched entity. + * @param column + * column field. + */ + static void setFieldValue(DBObject document, Object entityObject, Attribute column) + { + Object value = document.get(((AbstractAttribute) column).getJPAColumnName()); + if (value != null) + { + Class javaType = column.getJavaType(); + try + { + switch (AttributeType.getType(javaType)) + { + case MAP: + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), + ((BasicDBObject) value).toMap()); + break; + case SET: + List collectionValues = Arrays.asList(((BasicDBList) value).toArray()); + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), new HashSet( + collectionValues)); + break; + case LIST: + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), + Arrays.asList(((BasicDBList) value).toArray())); + break; + case POINT: + + BasicDBList list = (BasicDBList) value; + + Object xObj = list.get(0); + Object yObj = list.get(1); + + if (xObj != null && yObj != null) + { + try + { + double x = Double.parseDouble(xObj.toString()); + double y = Double.parseDouble(yObj.toString()); + + Point point = new Point(x, y); + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), point); + } + catch (NumberFormatException e) + { + log.error( + "Error while reading geolocation data for column {} ; Reason - possible corrupt data, Caused by : .", + column, e); + throw new EntityReaderException("Error while reading geolocation data for column " + column + + "; Reason - possible corrupt data.", e); + } + } + break; + case ENUM: + EnumAccessor accessor = new EnumAccessor(); + value = accessor.fromString(javaType, value.toString()); + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), value); + break; + case PRIMITIVE: + value = MongoDBUtils.populateValue(value, value.getClass()); + value = MongoDBUtils.getTranslatedObject(value, value.getClass(), javaType); + PropertyAccessorHelper.set(entityObject, (Field) column.getJavaMember(), value); + break; + } + } + catch (PropertyAccessException paex) + { + log.error("Error while setting column {} value, caused by : .", + ((AbstractAttribute) column).getJPAColumnName(), paex); + throw new PersistenceException(paex); + } + } + } + + /** + * Extract entity field. + * + * @param entity + * the entity + * @param dbObj + * the db obj + * @param column + * the column + * @throws PropertyAccessException + * the property access exception + */ + static void extractFieldValue(Object entity, DBObject dbObj, Attribute column) throws PropertyAccessException + { + try + { + Object valueObject = PropertyAccessorHelper.getObject(entity, (Field) column.getJavaMember()); + + if (valueObject != null) + { + Class javaType = column.getJavaType(); + switch (AttributeType.getType(javaType)) + { + case MAP: + Map mapObj = (Map) valueObject; + BasicDBObjectBuilder builder = BasicDBObjectBuilder.start(mapObj); + dbObj.put(((AbstractAttribute) column).getJPAColumnName(), builder.get()); + break; + case SET: + case LIST: + Collection collection = (Collection) valueObject; + BasicDBList basicDBList = new BasicDBList(); + for (Object o : collection) + { + basicDBList.add(o); + } + dbObj.put(((AbstractAttribute) column).getJPAColumnName(), basicDBList); + break; + case POINT: + + Point p = (Point) valueObject; + double[] coordinate = new double[] { p.getX(), p.getY() }; + dbObj.put(((AbstractAttribute) column).getJPAColumnName(), coordinate); + break; + case ENUM: + case PRIMITIVE: + dbObj.put(((AbstractAttribute) column).getJPAColumnName(), + MongoDBUtils.populateValue(valueObject, javaType)); + break; + } + } + } + catch (PropertyAccessException paex) + { + log.error("Error while getting column {} value, caused by : .", + ((AbstractAttribute) column).getJPAColumnName(), paex); + throw new PersistenceException(paex); + } + } + + /** + * Creates a collection of embeddedObjectClass instances + * wherein each element is java object representation of MongoDB document + * object contained in documentList. Field names are determined + * from columns. + * + * @param documentList + * the document list + * @param embeddedCollectionClass + * the embedded collection class + * @param embeddedObjectClass + * the embedded object class + * @param columns + * the columns + * @return the collection from document list + */ + static Collection getCollectionFromDocumentList(BasicDBList documentList, Class embeddedCollectionClass, + Class embeddedObjectClass, Set columns) + { + Collection embeddedCollection = null; + if (embeddedCollectionClass.equals(Set.class)) + { + embeddedCollection = new HashSet(); + } + else if (embeddedCollectionClass.equals(List.class)) + { + embeddedCollection = new ArrayList(); + } + else + { + throw new PersistenceException("Invalid collection class " + embeddedCollectionClass + + "; only Set and List allowed"); + } + + for (Object dbObj : documentList) + { + embeddedCollection.add(getObjectFromDocument((BasicDBObject) dbObj, embeddedObjectClass, columns)); + } + + return embeddedCollection; + } +} \ No newline at end of file diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClient.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClient.java new file mode 100644 index 000000000..0d60fa663 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClient.java @@ -0,0 +1,833 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.NotImplementedException; +import org.bson.types.ObjectId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.query.MongoDBQuery; +import com.impetus.client.mongodb.utils.MongoDBUtils; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.generator.AutoGenerator; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.index.IndexManager; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.ClientMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.DBEncoder; +import com.mongodb.DBObject; +import com.mongodb.DefaultDBEncoder; +import com.mongodb.WriteConcern; + +/** + * CLient class for MongoDB database. + * + * @author impetusopensource + */ +public class MongoDBClient extends ClientBase implements Client, Batcher, ClientPropertiesSetter, + AutoGenerator +{ + /** The mongo db. */ + private DB mongoDb; + + /** The reader. */ + private EntityReader reader; + + /** The data handler. */ + private MongoDBDataHandler handler; + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(MongoDBClient.class); + + private List nodes = new ArrayList(); + + private int batchSize; + + private WriteConcern writeConcern = null; + + private DBEncoder encoder = DefaultDBEncoder.FACTORY.create(); + + private Map puProperties; + + /** + * Instantiates a new mongo db client. + * + * @param mongo + * the mongo + * @param mgr + * the mgr + * @param reader + * the reader + * @param puProperties + */ + public MongoDBClient(Object mongo, IndexManager mgr, EntityReader reader, String persistenceUnit, + Map puProperties, ClientMetadata clientMetadata) + { + // TODO: This could be a constly call, see how connection pooling is + // relevant here + this.mongoDb = (DB) mongo; + this.indexManager = mgr; + this.reader = reader; + this.persistenceUnit = persistenceUnit; + this.puProperties = puProperties; + handler = new MongoDBDataHandler(); + this.clientMetadata = clientMetadata; + + populateBatchSize(persistenceUnit, this.puProperties); + + } + + @Override + public void persistJoinTable(JoinTableData joinTableData) + { + String joinTableName = joinTableData.getJoinTableName(); + String joinColumnName = joinTableData.getJoinColumnName(); + String invJoinColumnName = joinTableData.getInverseJoinColumnName(); + Map> joinTableRecords = joinTableData.getJoinTableRecords(); + + DBCollection dbCollection = mongoDb.getCollection(joinTableName); + List documents = new ArrayList(); + + for (Object key : joinTableRecords.keySet()) + { + Set values = joinTableRecords.get(key); + Object joinColumnValue = key; + + for (Object childId : values) + { + DBObject dbObj = new BasicDBObject(); + dbObj.put("_id", joinColumnValue.toString() + childId); + dbObj.put(joinColumnName, MongoDBUtils.populateValue(joinColumnValue, joinColumnValue.getClass())); + dbObj.put(invJoinColumnName, MongoDBUtils.populateValue(childId, childId.getClass())); + documents.add(dbObj); + } + } + dbCollection.insert(documents.toArray(new BasicDBObject[0]), getWriteConcern(), encoder); + } + + @Override + public List getColumnsById(String schemaName, String joinTableName, String joinColumnName, + String inverseJoinColumnName, Object parentId, Class columnJavaType) + { + List foreignKeys = new ArrayList(); + + DBCollection dbCollection = mongoDb.getCollection(joinTableName); + BasicDBObject query = new BasicDBObject(); + + query.put(joinColumnName, MongoDBUtils.populateValue(parentId, parentId.getClass())); + + DBCursor cursor = dbCollection.find(query); + DBObject fetchedDocument = null; + + while (cursor.hasNext()) + { + fetchedDocument = cursor.next(); + Object foreignKey = fetchedDocument.get(inverseJoinColumnName); + foreignKey = MongoDBUtils.getTranslatedObject(foreignKey, foreignKey.getClass(), columnJavaType); + foreignKeys.add((E) foreignKey); + } + return foreignKeys; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#findIdsByColumn(java.lang.String, + * java.lang.String, java.lang.String, java.lang.Object, java.lang.Class) + */ + @Override + public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName, + Object columnValue, Class entityClazz) + { + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(entityClazz); + + List primaryKeys = new ArrayList(); + + DBCollection dbCollection = mongoDb.getCollection(tableName); + BasicDBObject query = new BasicDBObject(); + + query.put(columnName, MongoDBUtils.populateValue(columnValue, columnValue.getClass())); + + DBCursor cursor = dbCollection.find(query); + DBObject fetchedDocument = null; + + while (cursor.hasNext()) + { + fetchedDocument = cursor.next(); + Object primaryKey = fetchedDocument.get(pKeyName); + primaryKey = MongoDBUtils.getTranslatedObject(primaryKey, primaryKey.getClass(), metadata.getIdAttribute() + .getJavaType()); + primaryKeys.add(primaryKey); + } + + if (primaryKeys != null && !primaryKeys.isEmpty()) + { + return primaryKeys.toArray(new Object[0]); + } + return null; + + } + + /* + * (non-Javadoc) + * + * @seecom.impetus.kundera.Client#loadColumns(com.impetus.kundera.ejb. + * EntityManager, java.lang.Class, java.lang.String, java.lang.String, + * java.lang.String, com.impetus.kundera.metadata.EntityMetadata) + */ + @Override + public Object find(Class entityClass, Object key) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + + List relationNames = entityMetadata.getRelationNames(); + + if (log.isDebugEnabled()) + { + log.debug("Fetching data from " + entityMetadata.getTableName() + " for PK " + key); + } + + DBCollection dbCollection = mongoDb.getCollection(entityMetadata.getTableName()); + + BasicDBObject query = new BasicDBObject(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + if (metaModel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType())) + { + MongoDBUtils.populateCompoundKey(query, entityMetadata, metaModel, key); + } + else + { + query.put("_id", MongoDBUtils.populateValue(key, key.getClass())); + } + + // DBCursor cursor = dbCollection.findOne(query); + DBObject fetchedDocument = dbCollection.findOne(query); + + /* + * if (cursor.hasNext()) { fetchedDocument = cursor.next(); } else { + * return null; } + */ + + if (fetchedDocument != null) + { + Object enhancedEntity = handler.getEntityFromDocument(entityMetadata.getEntityClazz(), entityMetadata, + fetchedDocument, relationNames); + + return enhancedEntity; + } + + return null; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#findAll(java.lang.Class, + * java.lang.Object[]) + */ + @Override + public List findAll(Class entityClass, String[] columnsToSelect, Object... keys) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entityClass); + + log.debug("Fetching data from " + entityMetadata.getTableName() + " for Keys " + keys); + + DBCollection dbCollection = mongoDb.getCollection(entityMetadata.getTableName()); + + BasicDBObject query = new BasicDBObject(); + + query.put("_id", new BasicDBObject("$in", keys)); + + DBCursor cursor = dbCollection.find(query); + + List entities = new ArrayList(); + while (cursor.hasNext()) + { + DBObject fetchedDocument = cursor.next(); + Object entity = handler.getEntityFromDocument(entityMetadata.getEntityClazz(), entityMetadata, + fetchedDocument, entityMetadata.getRelationNames()); + entities.add(entity); + } + return entities; + } + + /** + * Loads columns from multiple rows restricting results to conditions stored + * in filterClauseQueue. + * + * @param + * the element type + * @param entityMetadata + * the entity metadata + * @param mongoQuery + * the mongo query + * @param result + * the result + * @param relationNames + * the relation names + * @param orderBy + * the order by + * @param maxResult + * @param keys + * @return the list + * @throws Exception + * the exception + */ + public List loadData(EntityMetadata entityMetadata, BasicDBObject mongoQuery, List relationNames, + BasicDBObject orderBy, int maxResult, BasicDBObject keys, String... results) throws Exception + { + String documentName = entityMetadata.getTableName(); + Class clazz = entityMetadata.getEntityClazz(); + + DBCollection dbCollection = mongoDb.getCollection(documentName); + List entities = new ArrayList(); + + if (results != null && results.length > 0) + { + for (int i = 1; i < results.length; i++) + { + String result = results[i]; + + // If User wants search on a column within a particular super + // column, + // fetch that embedded object collection only + // otherwise retrieve whole entity + // TODO: improve code + if (result != null && result.indexOf(".") >= 0) + { + // TODO i need to discuss with Amresh before modifying it. + entities.addAll(handler.getEmbeddedObjectList(dbCollection, entityMetadata, documentName, + mongoQuery, result, orderBy, maxResult, keys)); + return entities; + } + } + } + log.debug("Fetching data from " + documentName + " for Filter " + mongoQuery.toString()); + + DBCursor cursor = orderBy != null ? dbCollection.find(mongoQuery, keys).sort(orderBy) : dbCollection.find( + mongoQuery, keys).limit(maxResult); + while (cursor.hasNext()) + { + DBObject fetchedDocument = cursor.next(); + Object entity = handler.getEntityFromDocument(clazz, entityMetadata, fetchedDocument, relationNames); + entities.add(entity); + } + return entities; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#delete(java.lang.Object, + * java.lang.Object) + */ + @Override + public void delete(Object entity, Object pKey) + { + EntityMetadata entityMetadata = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + + DBCollection dbCollection = mongoDb.getCollection(entityMetadata.getTableName()); + + // Find the DBObject to remove first + BasicDBObject query = new BasicDBObject(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + if (metaModel.isEmbeddable(entityMetadata.getIdAttribute().getBindableJavaType())) + { + MongoDBUtils.populateCompoundKey(query, entityMetadata, metaModel, pKey); + } + else + { + + query.put("_id", MongoDBUtils.populateValue(pKey, pKey.getClass())); + } + dbCollection.remove(query, getWriteConcern(), encoder); + getIndexManager().remove(entityMetadata, entity, pKey.toString()); + + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#close() + */ + @Override + public void close() + { + // TODO Once pool is implemented this code should not be there. + // Workaround for pool + this.indexManager.flush(); + puProperties = null; + } + + /** + * Creates the index. + * + * @param collectionName + * the collection name + * @param columnList + * the column list + * @param order + * the order + */ + public void createIndex(String collectionName, List columnList, int order) + { + DBCollection coll = mongoDb.getCollection(collectionName); + + List indexes = coll.getIndexInfo(); // List of all current + // indexes on collection + Set indexNames = new HashSet(); // List of all current + // index names + for (DBObject index : indexes) + { + BasicDBObject obj = (BasicDBObject) index.get("key"); + Set set = obj.keySet(); // Set containing index name which + // is key + indexNames.addAll(set); + } + + // Create index if not already created + for (String columnName : columnList) + { + if (!indexNames.contains(columnName)) + { + coll.createIndex(new BasicDBObject(columnName, order)); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#find(java.lang.Class, + * java.util.Map) + */ + @Override + public List find(Class entityClass, Map col) + { + throw new NotImplementedException("Not yet implemented"); + } + + /** + * Method to find entity for given association name and association value. + * + * @param colName + * the col name + * @param colValue + * the col value + * @param m + * the m + * @return the list + */ + public List findByRelation(String colName, Object colValue, Class entityClazz) + { + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClazz); + // you got column name and column value. + DBCollection dbCollection = mongoDb.getCollection(m.getTableName()); + + BasicDBObject query = new BasicDBObject(); + + query.put(colName, MongoDBUtils.populateValue(colValue, colValue.getClass())); + + DBCursor cursor = dbCollection.find(query); + DBObject fetchedDocument = null; + List results = new ArrayList(); + while (cursor.hasNext()) + { + fetchedDocument = cursor.next(); + Object entity = handler.getEntityFromDocument(m.getEntityClazz(), m, fetchedDocument, m.getRelationNames()); + results.add(entity); + } + + return results.isEmpty() ? null : results; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#getReader() + */ + @Override + public EntityReader getReader() + { + return reader; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#deleteByColumn(java.lang.String, + * java.lang.String, java.lang.Object) + */ + public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) + { + DBCollection dbCollection = mongoDb.getCollection(tableName); + BasicDBObject query = new BasicDBObject(); + query.put(columnName, columnValue); + dbCollection.remove(query, getWriteConcern(), encoder); + + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.client.Client#getQueryImplementor() + */ + @Override + public Class getQueryImplementor() + { + return MongoDBQuery.class; + } + + @Override + protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id, List rlHolders) + { + Map> collections = new HashMap>(); + collections = onPersist(collections, entity, id, entityMetadata, rlHolders, isUpdate); + onFlushCollection(collections); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.api.Batcher#addBatch(com.impetus.kundera + * .graph.Node) + */ + public void addBatch(Node node) + { + if (node != null) + { + nodes.add(node); + } + + onBatchLimit(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#getBatchSize() + */ + @Override + public int getBatchSize() + { + return batchSize; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#clear() + */ + @Override + public void clear() + { + if (nodes != null) + { + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + } + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.persistence.api.Batcher#executeBatch() + */ + @Override + public int executeBatch() + { + Map> collections = new HashMap>(); + for (Node node : nodes) + { + if (node.isDirty()) + { + node.handlePreEvent(); + // delete can not be executed in batch + if (node.isInState(RemovedState.class)) + { + delete(node.getData(), node.getEntityId()); + } + else + { + + List relationHolders = getRelationHolders(node); + EntityMetadata metadata = KunderaMetadataManager.getEntityMetadata(node.getDataClass()); + collections = onPersist(collections, node.getData(), node.getEntityId(), metadata, relationHolders, + node.isUpdate()); + indexNode(node, metadata); + } + node.handlePostEvent(); + } + } + + if (!collections.isEmpty()) + { + onFlushCollection(collections); + } + return collections.size(); + } + + /** + * On collections flush. + * + * @param collections + * collection containing records to be inserted in mongo db. + */ + private void onFlushCollection(Map> collections) + { + for (String tableName : collections.keySet()) + { + DBCollection dbCollection = mongoDb.getCollection(tableName); + dbCollection.insert(collections.get(tableName).toArray(new DBObject[0]), getWriteConcern(), encoder); + } + } + + /** + * Executes on list of entities to be persisted. + * + * @param collections + * collection containing list of db objects. + * @param entity + * entity in question. + * @param id + * entity id. + * @param metadata + * entity metadata + * @param relationHolders + * relation holders. + * @param isUpdate + * if it is an update + * @return collection of DB objects. + */ + private Map> onPersist(Map> collections, Object entity, Object id, + EntityMetadata metadata, List relationHolders, boolean isUpdate) + { + persistenceUnit = metadata.getPersistenceUnit(); + String documentName = metadata.getTableName(); + DBObject document = null; + document = new BasicDBObject(); + document = handler.getDocumentFromEntity(document, metadata, entity, relationHolders); + + if (isUpdate) + { + BasicDBObject query = new BasicDBObject(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + metadata.getPersistenceUnit()); + + if (metaModel.isEmbeddable(metadata.getIdAttribute().getBindableJavaType())) + { + MongoDBUtils.populateCompoundKey(query, metadata, metaModel, id); + } + else + { + query.put("_id", MongoDBUtils.populateValue(id, id.getClass())); + } + DBCollection dbCollection = mongoDb.getCollection(documentName); + //dbCollection.findAndModify(query, document); + + DBObject obj = dbCollection.findOne(query); + obj.putAll(document); + dbCollection.save(obj); + } + else + { + // a db collection can have multiple records.. + // and we can have a collection of records as well. + List dbStatements = null; + if (collections.containsKey(documentName)) + { + dbStatements = collections.get(documentName); + dbStatements.add(document); + } + else + { + dbStatements = new ArrayList(); + dbStatements.add(document); + collections.put(documentName, dbStatements); + } + } + + return collections; + } + + /** + * Check on batch limit. + */ + private void onBatchLimit() + { + if (batchSize > 0 && batchSize == nodes.size()) + { + executeBatch(); + nodes.clear(); + } + } + + @Override + public void populateClientProperties(Client client, Map properties) + { + new MongoDBClientProperties().populateClientProperties(client, properties); + } + + /** + * @param mongoDb + * the mongoDb to set + */ + public void setMongoDb(DB mongoDb) + { + this.mongoDb = mongoDb; + } + + /** + * @param handler + * the handler to set + */ + public void setHandler(MongoDBDataHandler handler) + { + this.handler = handler; + } + + /** + * @param nodes + * the nodes to set + */ + public void setNodes(List nodes) + { + this.nodes = nodes; + } + + /** + * @param writeConcern + * the writeConcern to set + */ + public void setWriteConcern(WriteConcern writeConcern) + { + this.writeConcern = writeConcern; + } + + /** + * @param encoder + * the encoder to set + */ + public void setEncoder(DBEncoder encoder) + { + this.encoder = encoder; + } + + /** + * @return the encoder + */ + public DBEncoder getEncoder() + { + return encoder; + } + + /** + * @return the writeConcern + */ + public WriteConcern getWriteConcern() + { + if (writeConcern == null) + { + return mongoDb.getWriteConcern(); + } + return writeConcern; + } + + /** + * @param batchSize + * the batchSize to set + */ + public void setBatchSize(int batchSize) + { + this.batchSize = batchSize; + } + + /** + * @param persistenceUnit + * @param puProperties + */ + private void populateBatchSize(String persistenceUnit, Map puProperties) + { + String batch_Size = puProperties != null ? (String) puProperties.get(PersistenceProperties.KUNDERA_BATCH_SIZE) + : null; + if (batch_Size != null) + { + batchSize = Integer.valueOf(batch_Size); + if (batchSize == 0) + { + throw new IllegalArgumentException("kundera.batch.size property must be numeric and > 0"); + } + } + else + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + batchSize = puMetadata.getBatchSize(); + } + } + + @Override + public Object generate() + { + // return auto generated id used by mongodb. + return new ObjectId(); + } + + /** + * Method to execute mongo jscripts. + * + * @param script + * jscript in string format + * + * @return result object. + */ + public Object executeScript(String script) + { + return mongoDb.eval(script); + } +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientFactory.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientFactory.java new file mode 100644 index 000000000..cb906de0c --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientFactory.java @@ -0,0 +1,387 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.net.SocketFactory; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.config.MongoDBPropertyReader; +import com.impetus.client.mongodb.config.MongoDBPropertyReader.MongoDBSchemaMetadata; +import com.impetus.client.mongodb.schemamanager.MongoDBSchemaManager; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.ClientProperties.DataStore.Connection.Server; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.ClientLoaderException; +import com.impetus.kundera.loader.GenericClientFactory; +import com.impetus.kundera.loader.KunderaAuthenticationException; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.mongodb.DB; +import com.mongodb.DBDecoderFactory; +import com.mongodb.DBEncoderFactory; +import com.mongodb.Mongo; +import com.mongodb.MongoException; +import com.mongodb.MongoOptions; +import com.mongodb.ServerAddress; + +/** + * A factory for creating MongoDBClient objects. + */ +public class MongoDBClientFactory extends GenericClientFactory +{ + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(MongoDBClientFactory.class); + + /** The mongo db. */ + private DB mongoDB; + + @Override + public void initialize(Map externalProperty) + { + reader = new MongoEntityReader(); + initializePropertyReader(); + setExternalProperties(externalProperty); + } + + @Override + protected Object createPoolOrConnection() + { + mongoDB = getConnection(); + return mongoDB; + } + + @Override + protected Client instantiateClient(String persistenceUnit) + { + return new MongoDBClient(mongoDB, indexManager, reader, persistenceUnit, externalProperties, clientMetadata); + } + + /** + * Gets the connection. + * + * @return the connection + */ + private DB getConnection() + { + + PersistenceUnitMetadata puMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + + Properties props = puMetadata.getProperties(); + String contactNode = null; + String defaultPort = null; + String keyspace = null; + String poolSize = null; + if (externalProperties != null) + { + contactNode = (String) externalProperties.get(PersistenceProperties.KUNDERA_NODES); + defaultPort = (String) externalProperties.get(PersistenceProperties.KUNDERA_PORT); + keyspace = (String) externalProperties.get(PersistenceProperties.KUNDERA_KEYSPACE); + poolSize = (String) externalProperties.get(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + } + if (contactNode == null) + { + contactNode = (String) props.get(PersistenceProperties.KUNDERA_NODES); + } + if (defaultPort == null) + { + defaultPort = (String) props.get(PersistenceProperties.KUNDERA_PORT); + } + if (keyspace == null) + { + keyspace = (String) props.get(PersistenceProperties.KUNDERA_KEYSPACE); + } + if (poolSize == null) + { + poolSize = props.getProperty(PersistenceProperties.KUNDERA_POOL_SIZE_MAX_ACTIVE); + } + + onValidation(contactNode, defaultPort); + + List addrs = new ArrayList(); + + Mongo mongo = null; + try + { + mongo = onSetMongoServerProperties(contactNode, defaultPort, poolSize, addrs); + + logger.info("Connected to mongodb at " + contactNode + " on port " + defaultPort); + } + catch (NumberFormatException e) + { + logger.error("Invalid format for MONGODB port, Unale to connect!" + "; Caused by:" + e.getMessage()); + throw new ClientLoaderException(e); + } + catch (UnknownHostException e) + { + logger.error("Unable to connect to MONGODB at host " + contactNode + "; Caused by:" + e.getMessage()); + throw new ClientLoaderException(e); + } + catch (MongoException e) + { + logger.error("Unable to connect to MONGODB; Caused by:" + e.getMessage()); + throw new ClientLoaderException(e); + } + + DB mongoDB = mongo.getDB(keyspace); + + authenticate(props, mongoDB); + logger.info("Connected to mongodb at " + contactNode + " on port " + defaultPort); + return mongoDB; + + } + + /** + * @param contactNode + * @param defaultPort + * @param poolSize + * @param addrs + * @return + * @throws UnknownHostException + */ + private Mongo onSetMongoServerProperties(String contactNode, String defaultPort, String poolSize, + List addrs) throws UnknownHostException + { + Mongo mongo = null; + MongoOptions mo = null; + MongoDBSchemaMetadata metadata = MongoDBPropertyReader.msmd; + ClientProperties cp = metadata != null ? metadata.getClientProperties() : null; + if (cp != null) + { + DataStore dataStore = metadata != null ? metadata.getDataStore() : null; + List servers = dataStore != null && dataStore.getConnection() != null ? dataStore.getConnection() + .getServers() : null; + if (servers != null && !servers.isEmpty()) + { + for (Server server : servers) + { + addrs.add(new ServerAddress(server.getHost(), Integer.parseInt(server.getPort()))); + } + mongo = new Mongo(addrs); + } + else + { + logger.info("Connecting to mongodb at " + contactNode + " on port " + defaultPort); + mongo = new Mongo(contactNode, Integer.parseInt(defaultPort)); + } + mo = mongo.getMongoOptions(); + Properties p = dataStore != null && dataStore.getConnection() != null ? dataStore.getConnection() + .getProperties() : null; + + PopulateMongoOptions.populateMongoOptions(mo, p); + } + else + { + logger.info("Connecting to mongodb at " + contactNode + " on port " + defaultPort); + mongo = new Mongo(contactNode, Integer.parseInt(defaultPort)); + mo = mongo.getMongoOptions(); + } + // setting server property. + + if (!StringUtils.isEmpty(poolSize)) + { + mo.connectionsPerHost = Integer.parseInt(poolSize); + } + return mongo; + } + + @Override + public boolean isThreadSafe() + { + return false; + } + + @Override + public void destroy() + { + indexManager.close(); + if (schemaManager != null) + { + schemaManager.dropSchema(); + } + if (mongoDB != null) + { + logger.info("Closing connection to mongodb."); + mongoDB.getMongo().close(); + logger.info("Closed connection to mongodb."); + } + else + { + logger.warn("Can't close connection to MONGODB, it was already disconnected"); + } + externalProperties = null; + schemaManager = null; + } + + @Override + public SchemaManager getSchemaManager(Map externalProperty) + { + if (schemaManager == null) + { + initializePropertyReader(); + setExternalProperties(externalProperty); + schemaManager = new MongoDBSchemaManager(MongoDBClientFactory.class.getName(), externalProperty); + } + return schemaManager; + } + + /** + * + */ + private void initializePropertyReader() + { + if (propertyReader == null) + { + propertyReader = new MongoDBPropertyReader(externalProperties); + propertyReader.read(getPersistenceUnit()); + } + } + + /** + * Method to authenticate connection with mongodb. throws runtime error if: + * a) userName and password, any one is not null. b) if authentication + * fails. + * + * + * @param props + * persistence properties. + * @param mongoDB + * mongo db connection. + */ + private void authenticate(Properties props, DB mongoDB) + { + String password = null; + String userName = null; + if (externalProperties != null) + { + userName = (String) externalProperties.get(PersistenceProperties.KUNDERA_USERNAME); + password = (String) externalProperties.get(PersistenceProperties.KUNDERA_PASSWORD); + } + if (userName == null) + { + userName = (String) props.get(PersistenceProperties.KUNDERA_USERNAME); + } + if (password == null) + { + password = (String) props.get(PersistenceProperties.KUNDERA_PASSWORD); + } + boolean authenticate = true; + String errMsg = null; + if (userName != null && password != null) + { + authenticate = mongoDB.authenticate(userName, password.toCharArray()); + } + else if ((userName != null && password == null) || (userName == null && password != null)) + { + errMsg = "Invalid configuration provided for authentication, please specify both non-nullable 'kundera.username' and 'kundera.password' properties"; + logger.error(errMsg); + throw new ClientLoaderException(errMsg); + } + + if (!authenticate) + { + errMsg = "Authentication failed, invalid 'kundera.username' :" + userName + "and 'kundera.password' :" + + password + " provided"; + throw new KunderaAuthenticationException(errMsg); + } + } + + public static class PopulateMongoOptions + { + private static Logger logger = LoggerFactory.getLogger(PopulateMongoOptions.class); + + public static void populateMongoOptions(MongoOptions mo, Properties props) + { + if (props != null && mo != null) + { + if (props.get(MongoDBConstants.DB_DECODER_FACTORY) != null) + { + mo.setDbDecoderFactory((DBDecoderFactory) props.get(MongoDBConstants.DB_DECODER_FACTORY)); + } + if (props.get(MongoDBConstants.DB_ENCODER_FACTORY) != null) + { + mo.setDbEncoderFactory((DBEncoderFactory) props.get(MongoDBConstants.DB_ENCODER_FACTORY)); + } + + mo.setAutoConnectRetry(Boolean.parseBoolean((String) props.get(MongoDBConstants.AUTO_CONNECT_RETRY))); + mo.setFsync(Boolean.parseBoolean((String) props.get(MongoDBConstants.FSYNC))); + mo.setJ(Boolean.parseBoolean((String) props.get(MongoDBConstants.J))); + + if (props.get(MongoDBConstants.SAFE) != null) + { + mo.setSafe((Boolean) props.get(MongoDBConstants.SAFE)); + } + if (props.get(MongoDBConstants.SOCKET_FACTORY) != null) + { + mo.setSocketFactory((SocketFactory) props.get(MongoDBConstants.SOCKET_FACTORY)); + } + + try + { + if (props.get(MongoDBConstants.CONNECTION_PER_HOST) != null) + { + mo.setConnectTimeout(Integer.parseInt((String) props.get(MongoDBConstants.CONNECT_TIME_OUT))); + } + if (props.get(MongoDBConstants.MAX_WAIT_TIME) != null) + { + mo.setMaxWaitTime(Integer.parseInt((String) props.get(MongoDBConstants.MAX_WAIT_TIME))); + } + if (props.get(MongoDBConstants.TABCM) != null) + { + mo.setThreadsAllowedToBlockForConnectionMultiplier(Integer.parseInt((String) props + .get(MongoDBConstants.TABCM))); + } + if (props.get(MongoDBConstants.W) != null) + { + mo.setW(Integer.parseInt((String) props.get(MongoDBConstants.W))); + } + if (props.get(MongoDBConstants.W_TIME_OUT) != null) + { + mo.setWtimeout(Integer.parseInt((String) props.get(MongoDBConstants.W_TIME_OUT))); + } + if (props.get(MongoDBConstants.MAX_AUTO_CONNECT_RETRY) != null) + { + mo.setMaxAutoConnectRetryTime(Long.parseLong((String) props + .get(MongoDBConstants.MAX_AUTO_CONNECT_RETRY))); + } + } + catch (NumberFormatException nfe) + { + logger.warn("Error while setting mongo properties, caused by :" + nfe); + } + } + } + } + + @Override + protected void initializeLoadBalancer(String loadBalancingPolicyName) + { + throw new UnsupportedOperationException("Load balancing feature is not supported in " + + this.getClass().getSimpleName()); + } +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientProperties.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientProperties.java new file mode 100644 index 000000000..1ea222cdd --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBClientProperties.java @@ -0,0 +1,74 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb; + +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.mongodb.DBEncoder; +import com.mongodb.WriteConcern; + +/** + * MongoDB implementation of {@link ClientPropertiesSetter} + * + * @author amresh.singh + */ +public class MongoDBClientProperties +{ + /** log for this class. */ + private static Logger log = LoggerFactory.getLogger(MongoDBClientProperties.class); + + public static final String WRITE_CONCERN = "write.concern"; + + public static final String DB_ENCODER = "db.encoder"; + + public static final String BATCH_SIZE = "batch.size"; + + public void populateClientProperties(Client client, Map properties) + { + MongoDBClient mongoDBClient = (MongoDBClient) client; + + if (properties != null) + { + for (String key : properties.keySet()) + { + Object value = properties.get(key); + + if (key.equals(WRITE_CONCERN) && value instanceof WriteConcern) + { + mongoDBClient.setWriteConcern((WriteConcern) value); + } + else if (key.equals(DB_ENCODER) && value instanceof DBEncoder) + { + mongoDBClient.setEncoder((DBEncoder) value); + } + else if (key.equals(BATCH_SIZE) && value instanceof Integer) + { + Integer batchSize = (Integer) value; + mongoDBClient.setBatchSize(batchSize); + } + + // Add more properties as needed + } + } + } +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBConstants.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBConstants.java new file mode 100644 index 000000000..4d9c66604 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBConstants.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +/** + * Holds constants for kundera-mongo module + * + * @author Kuldeep Mishra + * + */ +public interface MongoDBConstants +{ + public final static String CONNECTIONS = "mongodb.servers"; + + public final static String SOCKET_TIMEOUT = "socket.timeout"; + + public final static String READ_PREFERENCE = "read.preference"; + + public final static String AUTO_CONNECT_RETRY = "autoconnect.retry"; + + public static final String CONNECTION_PER_HOST = "connection.perhost"; + + public static final String CONNECT_TIME_OUT = "connection.timeout"; + + public static final String DB_DECODER_FACTORY = "dbdecoder.factory"; + + public static final String DB_ENCODER_FACTORY = "dbencoder.factory"; + + public static final String FSYNC = "fsync"; + + public static final String MAX_AUTO_CONNECT_RETRY = "max.autoconnect.retry"; + + public static final String J = "j"; + + public static final String MAX_WAIT_TIME = "maxwait.time"; + + public static final String SAFE = "safe"; + + public static final String SOCKET_FACTORY = "socket.factory"; + + public static final String TABCM = "threadsallowed.block.connectionmultiplier"; + + public static final String W = "w"; + + public static final String W_TIME_OUT = "w.timeout"; + + // public static final int DEFAULT_MAX_WAIT_TIME = 120000; + // + // public static final int DEFAULT_TABCM = 5; + public static final String CAPPED = "capped"; + + public static final String SIZE = "size"; + + public static final String MAX = "max"; + + public static final String MIN = "min"; + + public final static String WRITE_CONCERN = "write.concern"; +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBDataHandler.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBDataHandler.java new file mode 100644 index 000000000..f8b088535 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoDBDataHandler.java @@ -0,0 +1,471 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.persistence.PersistenceException; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.utils.MongoDBUtils; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessException; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.DBObject; + +/** + * Provides utility methods for handling data held in MongoDB. + * + * @author amresh.singh + */ +final class MongoDBDataHandler +{ + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(MongoDBDataHandler.class); + + /** + * Gets the entity from document. + * + * @param entityClass + * the entity class + * @param m + * the m + * @param document + * the document + * @param relations + * the relations + * @return the entity from document + */ + Object getEntityFromDocument(Class entityClass, EntityMetadata m, DBObject document, List relations) + { + // Entity object + Object entity = null; + + // Map to hold property-name=>foreign-entity relations + try + { + entity = entityClass.newInstance(); + + // Populate primary key column + Object rowKey = document.get("_id"); + Class rowKeyValueClass = rowKey.getClass(); + Class idClass = null; + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + Map relationValue = null; + idClass = m.getIdAttribute().getJavaType(); + rowKey = MongoDBUtils.populateValue(rowKey, idClass); + + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + EmbeddableType embeddable = metaModel.embeddable(m.getIdAttribute().getBindableJavaType()); + Iterator iter = embeddable.getAttributes().iterator(); + Object compoundKey = m.getIdAttribute().getBindableJavaType().newInstance(); + while (iter.hasNext()) + { + AbstractAttribute compositeAttrib = (AbstractAttribute) iter.next(); + Object value = ((BasicDBObject) rowKey).get(compositeAttrib.getJPAColumnName()); + PropertyAccessorHelper.set(compoundKey, (Field) compositeAttrib.getJavaMember(), value); + } + PropertyAccessorHelper.setId(entity, m, compoundKey); + } + else + { + rowKey = MongoDBUtils.getTranslatedObject(rowKey, rowKeyValueClass, idClass); + PropertyAccessorHelper.setId(entity, m, rowKey); + + } + + // Populate entity columns + // List columns = m.getColumnsAsList(); + EntityType entityType = metaModel.entity(entityClass); + + Set columns = entityType.getAttributes(); + + for (Attribute column : columns) + { + if (!column.equals(m.getIdAttribute())) + { + String fieldName = ((AbstractAttribute) column).getJPAColumnName(); + + Class javaType = ((AbstractAttribute) column).getBindableJavaType(); + if (metaModel.isEmbeddable(javaType)) + { + onViaEmbeddable(entityType, column, m, entity, metaModel.embeddable(javaType), document); + } + else if (!column.isAssociation()) + { + DocumentObjectMapper.setFieldValue(document, entity, column); + } + else if (relations != null) + { + if (relationValue == null) + { + relationValue = new HashMap(); + } + + if (relations.contains(fieldName) + && !fieldName.equals(((AbstractAttribute) m.getIdAttribute()).getJPAColumnName())) + { + Object colValue = document.get(fieldName); + if (colValue != null) + { + String colFieldName = m.getFieldName(fieldName); + Attribute attribute = colFieldName != null ? entityType.getAttribute(colFieldName) + : null; + EntityMetadata relationMetadata = KunderaMetadataManager.getEntityMetadata(attribute + .getJavaType()); + colValue = MongoDBUtils.getTranslatedObject(colValue, colValue.getClass(), + relationMetadata.getIdAttribute().getJavaType()); + } + relationValue.put(fieldName, colValue); + } + } + } + } + + if (relationValue != null && !relationValue.isEmpty()) + { + EnhanceEntity e = new EnhanceEntity(entity, PropertyAccessorHelper.getId(entity, m), relationValue); + return e; + } + else + { + return entity; + } + } + catch (InstantiationException e) + { + log.error("Error while instantiating " + entityClass + ", Caused by: ", e); + return entity; + } + catch (IllegalAccessException e) + { + log.error("Error while Getting entity from Document, Caused by: ", e); + return entity; + } + catch (PropertyAccessException e) + { + log.error("Error while Getting entity from Document, Caused by: ", e); + return entity; + } + + } + + /** + * Gets the document from entity. + * + * @param m + * the m + * @param entity + * the entity + * @param relations + * the relations + * @return the document from entity + * @throws PropertyAccessException + * the property access exception + */ + DBObject getDocumentFromEntity(DBObject dbObj, EntityMetadata m, Object entity, List relations) + throws PropertyAccessException + { + // List columns = m.getColumnsAsList(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + // Populate Row Key + Object id = PropertyAccessorHelper.getId(entity, m); + + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + MongoDBUtils.populateCompoundKey(dbObj, m, metaModel, id); + } + else + { + dbObj.put("_id", MongoDBUtils.populateValue(id, id.getClass())); + } + // Populate columns + // for (Column column : columns) + Set columns = entityType.getAttributes(); + for (Attribute column : columns) + { + if (!column.equals(m.getIdAttribute())) + { + try + { + Class javaType = ((AbstractAttribute) column).getBindableJavaType(); + if (metaModel.isEmbeddable(javaType)) + { + dbObj = onEmbeddable(entityType, column, m, entity, metaModel.embeddable(javaType), dbObj); + } + else if (!column.isAssociation()) + { + DocumentObjectMapper.extractFieldValue(entity, dbObj, column); + } + } + catch (PropertyAccessException paex) + { + log.error("Can't access property " + column.getName()); + } + } + } + if (relations != null) + { + for (RelationHolder rh : relations) + { + dbObj.put(rh.getRelationName(), + MongoDBUtils.populateValue(rh.getRelationValue(), rh.getRelationValue().getClass())); + } + } + return dbObj; + } + + /** + * Returns column name from the filter property which is in the form + * dbName.columnName + * + * @param filterProperty + * the filter property + * @return the column name + */ + private String getColumnName(String filterProperty) + { + StringTokenizer st = new StringTokenizer(filterProperty, "."); + String columnName = ""; + while (st.hasMoreTokens()) + { + columnName = st.nextToken(); + } + + return columnName; + } + + /** + * Retrieves A collection of embedded object within a document that match a + * criteria specified in query TODO: This code requires a + * serious overhawl. Currently it assumes that user query is in the form + * "Select alias.columnName from EntityName alias". However, correct query + * to be supported is + * "Select alias.superColumnName.columnName from EntityName alias" + * + * @param dbCollection + * the db collection + * @param m + * the m + * @param documentName + * the document name + * @param mongoQuery + * the mongo query + * @param result + * the result + * @param orderBy + * the order by + * @param maxResult + * @return the embedded object list + * @throws PropertyAccessException + * the property access exception + */ + List getEmbeddedObjectList(DBCollection dbCollection, EntityMetadata m, String documentName, + BasicDBObject mongoQuery, String result, BasicDBObject orderBy, int maxResult, BasicDBObject keys) + throws PropertyAccessException + { + List list = new ArrayList();// List of embedded object to be returned + + // MongoDBQuery mongoDBQuery = (MongoDBQuery) query; + + // Specified after entity alias in query + String columnName = result /* getColumnName(result) */; + + // Something user didn't specify and we have to derive + // TODO: User must specify this in query and remove this logic once + // query format is changed + // String enclosingDocumentName = getEnclosingDocumentName(m, + // columnName); + + String enclosingDocumentName = null; + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + EmbeddableType superColumn = null; + Set columns = null; + Attribute attrib = null; + try + { + attrib = entityType.getAttribute(columnName); + // if (!m.getColumnFieldNames().contains(columnName)) + // { + Map embeddables = metaModel.getEmbeddables(m.getEntityClazz()); + for (String key : embeddables.keySet()) + // for (EmbeddedColumn superColumn : m.getEmbeddedColumnsAsList()) + { + superColumn = embeddables.get(key); + // List columns = superColumn.getColumns(); + columns = superColumn.getAttributes(); + + for (Attribute column : columns) + { + if (((AbstractAttribute) column).getJPAColumnName().equals(columnName)) + { + enclosingDocumentName = key; + break; + } + } + } + } + catch (IllegalArgumentException iax) + { + log.info("No column found for: " + columnName); + } + + // Query for fetching entities based on user specified criteria + DBCursor cursor = orderBy != null ? dbCollection.find(mongoQuery, keys).sort(orderBy) : dbCollection.find( + mongoQuery, keys).limit(maxResult); + + // EmbeddableType superColumn = + // m.getEmbeddedColumn(enclosingDocumentName); + + if (superColumn != null) + { + Field superColumnField = (Field) attrib.getJavaMember(); + while (cursor.hasNext()) + { + DBObject fetchedDocument = cursor.next(); + Object embeddedDocumentObject = fetchedDocument.get(superColumnField.getName()); + + if (embeddedDocumentObject != null) + { + if (embeddedDocumentObject instanceof BasicDBList) + { + Class embeddedObjectClass = PropertyAccessorHelper.getGenericClass(superColumnField); + for (Object dbObj : (BasicDBList) embeddedDocumentObject) + { + Object embeddedObject = new DocumentObjectMapper().getObjectFromDocument( + (BasicDBObject) dbObj, embeddedObjectClass, superColumn.getAttributes()); + Object fieldValue = PropertyAccessorHelper.getObject(embeddedObject, columnName); + } + } + else if (embeddedDocumentObject instanceof BasicDBObject) + { + Object embeddedObject = DocumentObjectMapper.getObjectFromDocument( + (BasicDBObject) embeddedDocumentObject, superColumn.getJavaType(), + superColumn.getAttributes()); + list.add(embeddedObject); + + } + else + { + throw new PersistenceException("Can't retrieve embedded object from MONGODB document coz " + + "it wasn't stored as BasicDBObject, possible problem in format."); + } + } + } + } + return list; + } + + /** + * @param entityType + * @param column + * @param m + * @param entity + */ + private DBObject onEmbeddable(EntityType entityType, Attribute column, EntityMetadata m, Object entity, + EmbeddableType embeddableType, DBObject dbObj) + { + + Object embeddedObject = PropertyAccessorHelper.getObject(entity, (Field) column.getJavaMember()); + if (embeddedObject != null) + { + if (column.isCollection()) + { + Collection embeddedCollection = (Collection) embeddedObject; + // means it is case of element collection + + dbObj.put( + ((AbstractAttribute) column).getJPAColumnName(), + DocumentObjectMapper.getDocumentListFromCollection(embeddedCollection, + embeddableType.getAttributes())); + } + else + { + dbObj.put(((AbstractAttribute) column).getJPAColumnName(), + DocumentObjectMapper.getDocumentFromObject(embeddedObject, embeddableType.getAttributes())); + } + } + + return dbObj; + } + + /** + * @param entityType + * @param column + * @param m + * @param entity + * @param embeddable + * @param document + */ + private void onViaEmbeddable(EntityType entityType, Attribute column, EntityMetadata m, Object entity, + EmbeddableType embeddable, DBObject document) + { + Field embeddedField = (Field) column.getJavaMember(); + Object embeddedDocumentObject = null; + if (column.isCollection()) + { + Class embeddedObjectClass = PropertyAccessorHelper.getGenericClass(embeddedField); + + embeddedDocumentObject = document.get(((AbstractAttribute) column).getJPAColumnName()); + + Collection embeddedCollection = DocumentObjectMapper.getCollectionFromDocumentList( + (BasicDBList) embeddedDocumentObject, embeddedField.getType(), embeddedObjectClass, + embeddable.getAttributes()); + PropertyAccessorHelper.set(entity, embeddedField, embeddedCollection); + } + else + { + embeddedDocumentObject = document.get(((AbstractAttribute) column).getJPAColumnName()); + PropertyAccessorHelper.set(entity, embeddedField, DocumentObjectMapper.getObjectFromDocument( + (BasicDBObject) embeddedDocumentObject, ((AbstractAttribute) column).getBindableJavaType(), + embeddable.getAttributes())); + } + } + +} \ No newline at end of file diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoEntityReader.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoEntityReader.java new file mode 100644 index 000000000..85751e18d --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/MongoEntityReader.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb; + +import java.util.List; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.AbstractEntityReader; +import com.impetus.kundera.persistence.EntityReader; + +/** + * The Class MongoEntityReader. Default entity reader for mongo db. + * + * @author vivek.mishra + */ +public class MongoEntityReader extends AbstractEntityReader implements EntityReader +{ + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.EntityReader#populateRelation(com.impetus + * .kundera.metadata.model.EntityMetadata, java.util.List, boolean, + * com.impetus.kundera.client.Client) + */ + @Override + public List populateRelation(EntityMetadata m, Client client, int maxResults) + { + throw new UnsupportedOperationException("Method supported not required for mongo"); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.persistence.EntityReader#findById(java.lang.String, + * com.impetus.kundera.metadata.model.EntityMetadata, java.util.List, + * com.impetus.kundera.client.Client) + */ + @Override + public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client) + { + return super.findById(primaryKey, m, client); + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/config/MongoDBPropertyReader.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/config/MongoDBPropertyReader.java new file mode 100644 index 000000000..0f62ea066 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/config/MongoDBPropertyReader.java @@ -0,0 +1,214 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb.config; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBConstants; +import com.impetus.kundera.configure.AbstractPropertyReader; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema; +import com.impetus.kundera.configure.ClientProperties.DataStore.Schema.Table; +import com.impetus.kundera.configure.PropertyReader; +import com.impetus.kundera.configure.schema.SchemaGenerationException; + +/** + * Mongo Property Reader reads mongo properties from property file + * {kundera-mongo.properties} and put it into mongo schema metadata. + * + * @author kuldeep.mishra + * + */ +public class MongoDBPropertyReader extends AbstractPropertyReader implements PropertyReader +{ + /** log instance */ + private static Logger log = LoggerFactory.getLogger(MongoDBPropertyReader.class); + + /** MongoDB schema metadata instance */ + public static MongoDBSchemaMetadata msmd; + + public MongoDBPropertyReader(Map externalProperties) + { + super(externalProperties); + msmd = new MongoDBSchemaMetadata(); + } + + public void onXml(ClientProperties cp) + { + if (cp != null) + { + msmd.setClientProperties(cp); + } + } + + /** + * MongoDBSchemaMetadata class holds property related to metadata + * + * @author kuldeep.mishra + * + */ + public class MongoDBSchemaMetadata + { + private ClientProperties clientProperties; + + public MongoDBSchemaMetadata() + { + + } + + /** + * @return the clientProperties + */ + public ClientProperties getClientProperties() + { + return clientProperties; + } + + /** + * @param clientProperties + * the clientProperties to set + */ + private void setClientProperties(ClientProperties clientProperties) + { + this.clientProperties = clientProperties; + } + + public DataStore getDataStore() + { + if (getClientProperties() != null && getClientProperties().getDatastores() != null) + { + for (DataStore dataStore : getClientProperties().getDatastores()) + { + if (dataStore.getName() != null && dataStore.getName().equalsIgnoreCase("mongo")) + { + return dataStore; + } + } + } + return null; + } + + /** + * @param databaseName + * @param tableName + * @return + */ + public boolean isCappedCollection(String databaseName, String tableName) + { + List schemas = getDataStore() != null ? getDataStore().getSchemas() : null; + if (schemas != null) + { + for (Schema schema : schemas) + { + if (schema != null && schema.getName() != null && schema.getName().equalsIgnoreCase(databaseName)) + { + for (Table table : schema.getTables()) + { + if (table.getProperties() != null && tableName.equals(table.getName())) + { + return Boolean.parseBoolean(table.getProperties().getProperty(MongoDBConstants.CAPPED)); + } + } + } + } + } + return false; + } + + /** + * @param databaseName + * @param tableName + * @return + */ + public int getCollectionSize(String databaseName, String tableName) + { + List schemas = getDataStore() != null ? getDataStore().getSchemas() : null; + if (schemas != null) + { + for (Schema schema : schemas) + { + if (schema != null && schema.getName() != null && schema.getName().equalsIgnoreCase(databaseName)) + { + for (Table table : schema.getTables()) + { + if (table.getProperties() != null) + { + try + { + String size = table.getProperties().getProperty(MongoDBConstants.SIZE); + if (size != null && !size.isEmpty()) + { + return Integer.parseInt(size); + } + } + catch (NumberFormatException nfe) + { + throw new SchemaGenerationException(nfe); + } + } + } + } + } + } + return 100000; + } + + /** + * @param databaseName + * @param tableName + * @return + */ + public int getMaxSize(String databaseName, String tableName) + { + List schemas = getDataStore() != null ? getDataStore().getSchemas() : null; + if (schemas != null) + { + for (Schema schema : schemas) + { + if (schema != null && schema.getName() != null && schema.getName().equalsIgnoreCase(databaseName)) + { + for (Table table : schema.getTables()) + { + if (table.getProperties() != null) + { + try + { + String max = table.getProperties().getProperty(MongoDBConstants.MAX); + if (max != null && !max.isEmpty()) + { + return Integer.parseInt(max); + } + } + catch (NumberFormatException nfe) + { + throw new SchemaGenerationException(nfe); + } + } + } + } + } + } + return 100; + } + } +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/index/IndexType.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/index/IndexType.java new file mode 100644 index 000000000..af77cdd7c --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/index/IndexType.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.index; + +/** + * MongoDB Index Type + * + * @author amresh.singh + */ +public enum IndexType +{ + ASC, DSC, GEO2D; + + public static String findByValue(IndexType value) + { + switch (value) + { + case ASC: + return "1"; + case DSC: + return "-1"; + case GEO2D: + return "2D"; + default: + return "1"; + } + } +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/MongoDBQuery.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/MongoDBQuery.java new file mode 100644 index 000000000..8ebc2b7a5 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/MongoDBQuery.java @@ -0,0 +1,493 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb.query; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Iterator; +import java.util.List; +import java.util.Queue; + +import javax.persistence.Parameter; +import javax.persistence.Query; +import javax.persistence.TemporalType; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; +import javax.persistence.metamodel.EntityType; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.mongodb.MongoEntityReader; +import com.impetus.client.mongodb.query.gis.GeospatialQueryFactory; +import com.impetus.client.mongodb.utils.MongoDBUtils; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.property.PropertyAccessorFactory; +import com.impetus.kundera.query.KunderaQuery; +import com.impetus.kundera.query.KunderaQuery.FilterClause; +import com.impetus.kundera.query.KunderaQuery.SortOrder; +import com.impetus.kundera.query.KunderaQuery.SortOrdering; +import com.impetus.kundera.query.QueryHandlerException; +import com.impetus.kundera.query.QueryImpl; +import com.mongodb.BasicDBObject; + +/** + * Query class for MongoDB data store. + * + * @author amresh.singh + */ +public class MongoDBQuery extends QueryImpl +{ + /** The log used by this class. */ + private static Logger log = LoggerFactory.getLogger(MongoDBQuery.class); + private boolean isSingleResult; + + /** + * Instantiates a new mongo db query. + * + * @param jpaQuery + * the jpa query + * @param kunderaQuery + * the kundera query + * @param persistenceDelegator + * the persistence delegator + * @param persistenceUnits + * the persistence units + */ + public MongoDBQuery(String jpaQuery, KunderaQuery kunderaQuery, PersistenceDelegator persistenceDelegator) + { + super(jpaQuery, persistenceDelegator); + this.kunderaQuery = kunderaQuery; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#executeUpdate() + */ + @Override + public int executeUpdate() + { + return super.executeUpdate(); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#setMaxResults(int) + */ + @Override + public Query setMaxResults(int maxResult) + { + return super.setMaxResults(maxResult); + } + + /* + * (non-Javadoc) + * + * @see + * com.impetus.kundera.query.QueryImpl#populateEntities(com.impetus.kundera + * .metadata.model.EntityMetadata, com.impetus.kundera.client.Client) + */ + + @Override + protected List populateEntities(EntityMetadata m, Client client) + { + try + { + BasicDBObject orderByClause = getOrderByClause(); + return ((MongoDBClient) client).loadData(m, createMongoQuery(m, getKunderaQuery().getFilterClauseQueue()), + null, orderByClause, isSingleResult ? 1 : maxResult, getKeys(m, getKunderaQuery().getResult()), getKunderaQuery() + .getResult()); + } + catch (Exception e) + { + log.error("Error during executing query, Caused by:", e); + throw new QueryHandlerException(e); + } + } + + @Override + public Object getSingleResult() + { + // to fetch a single result form database. + isSingleResult = true; + List results = getResultList(); + isSingleResult=false; + return results.isEmpty() ? results : results.get(0); + } + + @Override + protected List recursivelyPopulateEntities(EntityMetadata m, Client client) + { + // TODO : required to modify client return relation. + // if it is a parent..then find data related to it only + // else u need to load for associated fields too. + List ls = new ArrayList(); + try + { + BasicDBObject orderByClause = getOrderByClause(); + ls = ((MongoDBClient) client).loadData(m, createMongoQuery(m, getKunderaQuery().getFilterClauseQueue()), + m.getRelationNames(), orderByClause, isSingleResult ? 1 : maxResult, getKeys(m, getKunderaQuery().getResult()), + getKunderaQuery().getResult()); + } + catch (Exception e) + { + log.error("Error during executing query, Caused by:", e); + throw new QueryHandlerException(e); + } + + return setRelationEntities(ls, client, m); + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#getReader() + */ + @Override + protected EntityReader getReader() + { + return new MongoEntityReader(); + } + + /** + * Creates MongoDB Query object from filterClauseQueue. + * + * @param m + * the m + * @param filterClauseQueue + * the filter clause queue + * @param columns + * @return the basic db object + */ + private BasicDBObject createMongoQuery(EntityMetadata m, Queue filterClauseQueue) + { + BasicDBObject query = new BasicDBObject(); + BasicDBObject compositeColumns = new BasicDBObject(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + for (Object object : filterClauseQueue) + { + boolean isCompositeColumn = false; + + if (object instanceof FilterClause) + { + FilterClause filter = (FilterClause) object; + // String property = getColumnName(filter.getProperty()); + String property = filter.getProperty(); + String condition = filter.getCondition(); + // String value = filter.getValue().toString(); + Object value = filter.getValue(); + + // value is string but field.getType is different, then get + // value using + + Field f = null; + + // if alias is still present .. means it is an enclosing + // document search. + // + + if (((AbstractAttribute) m.getIdAttribute()).getJPAColumnName().equalsIgnoreCase(property)) + { + property = "_id"; + f = (Field) m.getIdAttribute().getJavaMember(); + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType()) + && value.getClass().isAssignableFrom(f.getType())) + { + EmbeddableType compoundKey = metaModel.embeddable(m.getIdAttribute().getBindableJavaType()); + compositeColumns = MongoDBUtils.getCompoundKeyColumns(m, value, compoundKey); + isCompositeColumn = true; + continue; + } + } + else if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType()) + && StringUtils.contains(property, '.')) + { + // Means it is a case of composite column. + property = property.substring(property.indexOf(".") + 1); + isCompositeColumn = true; + } + else + { + EntityType entity = metaModel.entity(m.getEntityClazz()); + String fieldName = m.getFieldName(property); + f = (Field) entity.getAttribute(fieldName).getJavaMember(); + } + + if (value.getClass().isAssignableFrom(String.class) && f != null + && !f.getType().equals(value.getClass())) + { + value = PropertyAccessorFactory.getPropertyAccessor(f).fromString(f.getType().getClass(), + value.toString()); + } + value = populateValue(value, value.getClass()); + + // Property, if doesn't exist in entity, may be there in a + // document embedded within it, so we have to check that + // TODO: Query should actually be in a format + // documentName.embeddedDocumentName.column, remove below if + // block once this is decided + + // Query could be geospatial in nature + if (f != null && f.getType().equals(Point.class)) + { + GeospatialQuery geospatialQueryimpl = GeospatialQueryFactory.getGeospatialQueryImplementor( + condition, value); + query = (BasicDBObject) geospatialQueryimpl.createGeospatialQuery(property, value, query); + + } + else + { + if (condition.equals("=")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, value); + } + else + { + query.append(property, value); + } + + } + else if (condition.equalsIgnoreCase("like")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, value); + } + else + { + query.append(property, value); + } + } + else if (condition.equalsIgnoreCase(">")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, new BasicDBObject("$gt", value)); + + } + else + { + if (query.containsField(property)) + { + query.get(property); + query.put(property, ((BasicDBObject) query.get(property)).append("$gt", value)); + } + else + { + query.append(property, new BasicDBObject("$gt", value)); + } + } + + } + else if (condition.equalsIgnoreCase(">=")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, new BasicDBObject("$gte", value)); + + } + else + { + if (query.containsField(property)) + + { + query.get(property); + query.put(property, ((BasicDBObject) query.get(property)).append("$gte", value)); + } + else + { + query.append(property, new BasicDBObject("$gte", value)); + } + } + } + else if (condition.equalsIgnoreCase("<")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, new BasicDBObject("$lt", value)); + + } + else + { + if (query.containsField(property)) + { + query.get(property); + query.put(property, ((BasicDBObject) query.get(property)).append("$lt", value)); + } + else + { + query.append(property, new BasicDBObject("$lt", value)); + } + } + } + else if (condition.equalsIgnoreCase("<=")) + { + if (isCompositeColumn) + { + compositeColumns.put(property, new BasicDBObject("$lte", value)); + + } + else + { + if (query.containsField(property)) + { + query.get(property); + query.put(property, ((BasicDBObject) query.get(property)).append("$lte", value)); + } + else + { + query.append(property, new BasicDBObject("$lte", value)); + } + } + } + } + + // TODO: Add support for other operators like >, <, >=, <=, + // order by asc/ desc, limit, skip, count etc + } + } + + if (!compositeColumns.isEmpty()) + { + query.append("_id", compositeColumns); + } + return query; + } + + private BasicDBObject getKeys(EntityMetadata m, String[] columns) + { + BasicDBObject keys = new BasicDBObject(); + if (columns != null && columns.length > 0) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entity = metaModel.entity(m.getEntityClazz()); + for (int i = 1; i < columns.length; i++) + { + if (columns[i] != null) + { + Attribute col = entity.getAttribute(columns[i]); + if (col == null) + { + throw new QueryHandlerException("column type is null for: " + columns); + } + keys.put(((AbstractAttribute) col).getJPAColumnName(), 1); + } + } + } + return keys; + } + + /** + * Prepare order by clause. + * + * @return order by clause. + */ + private BasicDBObject getOrderByClause() + { + BasicDBObject orderByClause = null; + + List orders = kunderaQuery.getOrdering(); + if (orders != null) + { + orderByClause = new BasicDBObject(); + for (SortOrdering order : orders) + { + orderByClause.append(order.getColumnName(), order.getColumnName().equals(SortOrder.ASC) ? 1 : -1); + } + } + + return orderByClause; + } + + /* + * (non-Javadoc) + * + * @see com.impetus.kundera.query.QueryImpl#onExecuteUpdate() + */ + @Override + protected int onExecuteUpdate() + { + if (kunderaQuery.isDeleteUpdate()) + { + List result = getResultList(); + return result != null ? result.size() : 0; + } + + return 0; + } + + /** + * @param valObj + * @return + */ + public Object populateValue(Object valObj, Class clazz) + { + if (isUTF8Value(clazz)) + { + return valObj.toString(); + } + return valObj; + } + + private boolean isUTF8Value(Class clazz) + { + return (clazz.isAssignableFrom(BigDecimal.class)) + || (clazz.isAssignableFrom(BigInteger.class) || (clazz.isAssignableFrom(String.class)) + || (clazz.isAssignableFrom(char.class)) || (clazz.isAssignableFrom(Character.class)) + || (clazz.isAssignableFrom(Calendar.class)) || (clazz.isAssignableFrom(GregorianCalendar.class))); + } + + @Override + public void close() + { + // TODO Auto-generated method stub + + } + + @Override + public Iterator iterate() + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/CircleQueryImpl.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/CircleQueryImpl.java new file mode 100644 index 000000000..03cd3b3e2 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/CircleQueryImpl.java @@ -0,0 +1,61 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import java.util.ArrayList; +import java.util.List; + +import com.impetus.kundera.gis.SurfaceType; +import com.impetus.kundera.gis.geometry.Circle; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.mongodb.BasicDBObject; + +/** + * Provides methods for geospatial queries specific to circle shape + * + * @author amresh.singh + */ +public class CircleQueryImpl implements GeospatialQuery +{ + @Override + public Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query) + { + Circle circle = (Circle) shape; + List circleList = new ArrayList(); + + circleList.add(new double[] { circle.getCentre().x, circle.getCentre().y }); // Centre + // of + // circle + circleList.add(circle.getRadius()); // Radius + + BasicDBObject q = (BasicDBObject) query; + + if (q == null) + q = new BasicDBObject(); + + if (circle.getSurfaceType().equals(SurfaceType.SPHERICAL)) + { + q.put(geolocationColumnName, new BasicDBObject("$within", new BasicDBObject("$centerSphere", circleList))); + } + else + { + q.put(geolocationColumnName, new BasicDBObject("$within", new BasicDBObject("$center", circleList))); + } + + return q; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/EnvelopeQueryImpl.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/EnvelopeQueryImpl.java new file mode 100644 index 000000000..5196e1482 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/EnvelopeQueryImpl.java @@ -0,0 +1,55 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import java.util.ArrayList; +import java.util.List; + +import com.impetus.kundera.gis.geometry.Envelope; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.mongodb.BasicDBObject; + +/** + * Provides methods for geospatial queries specific to box shape + * + * @author amresh.singh + */ +public class EnvelopeQueryImpl implements GeospatialQuery +{ + + @Override + public Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query) + { + List boxList = new ArrayList(); + + Envelope box = (Envelope) shape; + + boxList.add(new double[] { box.getMinX(), box.getMinY() }); // Starting + // coordinate + boxList.add(new double[] { box.getMaxX(), box.getMaxY() }); // Ending + // coordinate + + BasicDBObject q = (BasicDBObject) query; + + if (q == null) + q = new BasicDBObject(); + + q.put(geolocationColumnName, new BasicDBObject("$within", new BasicDBObject("$box", boxList))); + + return q; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/GeospatialQueryFactory.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/GeospatialQueryFactory.java new file mode 100644 index 000000000..dab61298c --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/GeospatialQueryFactory.java @@ -0,0 +1,69 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import com.impetus.kundera.gis.geometry.Circle; +import com.impetus.kundera.gis.geometry.Envelope; +import com.impetus.kundera.gis.geometry.Polygon; +import com.impetus.kundera.gis.geometry.Triangle; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.impetus.kundera.query.QueryHandlerException; + +/** + * Factory for {@link GeospatialQuery} + * + * @author amresh.singh + */ +public class GeospatialQueryFactory +{ + public static GeospatialQuery getGeospatialQueryImplementor(String operator, Object shape) + { + if (operator.equalsIgnoreCase("in")) + { + if (shape.getClass().isAssignableFrom(Circle.class)) + { + return new CircleQueryImpl(); + } + else if (shape.getClass().isAssignableFrom(Envelope.class)) + { + return new EnvelopeQueryImpl(); + } + else if (shape.getClass().isAssignableFrom(Triangle.class)) + { + return new TriangleQueryImpl(); + } + else if (shape.getClass().isAssignableFrom(Polygon.class)) + { + return new PolygonQueryImpl(); + } + else + { + throw new QueryHandlerException("Shape " + shape.getClass() + " is not supported" + + " in JPA queries for operator " + operator + " in Kundera currently"); + } + } + else if (operator.equals(">") || operator.equals(">=") || operator.equals("<") || operator.equals("<=")) + { + return new NearQueryImpl(); + } + else + { + throw new QueryHandlerException("Shape " + shape.getClass() + " is not supported" + + " in JPA queries for operator " + operator + " in Kundera currently"); + } + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/NearQueryImpl.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/NearQueryImpl.java new file mode 100644 index 000000000..846ba501d --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/NearQueryImpl.java @@ -0,0 +1,79 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import com.impetus.kundera.gis.SurfaceType; +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.mongodb.BasicDBObject; + +/** + * + * + * @author amresh.singh + */ +public class NearQueryImpl implements GeospatialQuery +{ + + @Override + public Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query) + { + BasicDBObject q = (BasicDBObject) query; + + if (q == null) + q = new BasicDBObject(); + + // Set point in query which is involved in near search + if (shape != null && shape.getClass().isAssignableFrom(Point.class)) + { + Point point = (Point) shape; + BasicDBObject filter = (BasicDBObject) q.get(geolocationColumnName); + + if (filter == null) + filter = new BasicDBObject(); + + if (point.getSurfaceType().equals(SurfaceType.SPHERICAL)) + { + filter.put("$nearSphere", new double[] { point.getX(), point.getY() }); + } + else + { + filter.put("$near", new double[] { point.getX(), point.getY() }); + } + + q.put(geolocationColumnName, filter); + } + + // Set maximum distance from the given point + if (shape != null + && (shape.getClass().isAssignableFrom(Double.class) || shape.getClass().isAssignableFrom(double.class))) + { + Double maxDistance = (Double) shape; + + BasicDBObject filter = (BasicDBObject) q.get(geolocationColumnName); + + if (filter == null) + filter = new BasicDBObject(); + + filter.put("$maxDistance", maxDistance); + + q.put(geolocationColumnName, filter); + } + + return q; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/PolygonQueryImpl.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/PolygonQueryImpl.java new file mode 100644 index 000000000..e5e678397 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/PolygonQueryImpl.java @@ -0,0 +1,55 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import java.util.ArrayList; +import java.util.List; + +import com.impetus.kundera.gis.geometry.Coordinate; +import com.impetus.kundera.gis.geometry.Polygon; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.mongodb.BasicDBObject; + +/** + * Provides methods for geospatial queries specific to polygon shape + * + * @author amresh.singh + */ +public class PolygonQueryImpl implements GeospatialQuery +{ + @Override + public Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query) + { + List polygonList = new ArrayList(); + + Polygon polygon = (Polygon) shape; + + for (Coordinate c : polygon.getCoordinates()) + { + polygonList.add(new double[] { c.x, c.y }); + } + + BasicDBObject q = (BasicDBObject) query; + + if (q == null) + q = new BasicDBObject(); + + q.put(geolocationColumnName, new BasicDBObject("$within", new BasicDBObject("$polygon", polygonList))); + + return q; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/TriangleQueryImpl.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/TriangleQueryImpl.java new file mode 100644 index 000000000..e2534275b --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/query/gis/TriangleQueryImpl.java @@ -0,0 +1,54 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.query.gis; + +import java.util.ArrayList; +import java.util.List; + +import com.impetus.kundera.gis.geometry.Triangle; +import com.impetus.kundera.gis.query.GeospatialQuery; +import com.mongodb.BasicDBObject; + +/** + * Provides methods for geospatial queries specific to triangle shape + * + * @author amresh.singh + */ +public class TriangleQueryImpl implements GeospatialQuery +{ + + @Override + public Object createGeospatialQuery(String geolocationColumnName, Object shape, Object query) + { + List triangleList = new ArrayList(); + + Triangle triangle = (Triangle) shape; + + triangleList.add(new double[] { triangle.p0.x, triangle.p0.y }); // A + triangleList.add(new double[] { triangle.p1.x, triangle.p1.y }); // B + triangleList.add(new double[] { triangle.p2.x, triangle.p2.y }); // C + + BasicDBObject q = (BasicDBObject) query; + + if (q == null) + q = new BasicDBObject(); + + q.put(geolocationColumnName, new BasicDBObject("$within", new BasicDBObject("$polygon", triangleList))); + + return q; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManager.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManager.java new file mode 100644 index 000000000..f473961b2 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManager.java @@ -0,0 +1,327 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.mongodb.schemamanager; + +import java.net.UnknownHostException; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBConstants; +import com.impetus.client.mongodb.config.MongoDBPropertyReader; +import com.impetus.client.mongodb.index.IndexType; +import com.impetus.kundera.configure.schema.IndexInfo; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.configure.schema.TableInfo; +import com.impetus.kundera.configure.schema.api.AbstractSchemaManager; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBObject; +import com.mongodb.Mongo; + +/** + * The Class MongoDBSchemaManager manages auto schema operation + * {@code ScheamOperationType} for mongoDb database. + * + * @author Kuldeep.kumar + * + */ +public class MongoDBSchemaManager extends AbstractSchemaManager implements SchemaManager +{ + + /** The m. */ + private Mongo mongo; + + /** The db. */ + private DB db; + + /** The coll. */ + private DBCollection coll; + + /** The Constant logger. */ + private static final Logger logger = LoggerFactory.getLogger(MongoDBSchemaManager.class); + + public MongoDBSchemaManager(String clientFactory, Map externalProperties) + { + super(clientFactory, externalProperties); + } + + @Override + /** + * Export schema handles the handleOperation method. + */ + public void exportSchema(final String persistenceUnit, List schemas) + { + super.exportSchema(persistenceUnit,schemas); + } + + /** + * drop schema method drop the table + */ + public void dropSchema() + { + if (operation != null && operation.equalsIgnoreCase("create-drop")) + { + for (TableInfo tableInfo : tableInfos) + { + coll = db.getCollection(tableInfo.getTableName()); + coll.drop(); + } + } + db = null; + } + + /** + * create method creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create(List tableInfos) + { + for (TableInfo tableInfo : tableInfos) + { + DBObject options = setCollectionProperties(tableInfo); + getDBName(); + DB db = mongo.getDB(databaseName); + if (db.collectionExists(tableInfo.getTableName())) + { + db.getCollection(tableInfo.getTableName()).drop(); + } + DBCollection collection = db.createCollection(tableInfo.getTableName(), options); + + boolean isCappedCollection = isCappedCollection(tableInfo); + if (!isCappedCollection) + { + createIndexes(tableInfo, collection); + } + } + } + + /** + * create_drop method creates schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void create_drop(List tableInfos) + { + create(tableInfos); + } + + /** + * update method update schema and table for the list of tableInfos + * + * @param tableInfos + * list of TableInfos. + */ + protected void update(List tableInfos) + { + for (TableInfo tableInfo : tableInfos) + { + DBObject options = setCollectionProperties(tableInfo); + getDBName(); + DB db = mongo.getDB(databaseName); + DBCollection collection = null; + if (!db.collectionExists(tableInfo.getTableName())) + { + collection = db.createCollection(tableInfo.getTableName(), options); + } + collection = collection != null ? collection : db.getCollection(tableInfo.getTableName()); + + boolean isCappedCollection = isCappedCollection(tableInfo); + if (!isCappedCollection) + { + createIndexes(tableInfo, collection); + } + } + } + + /** + * validate method validate schema and table for the list of tableInfos. + * + * @param tableInfos + * list of TableInfos. + */ + protected void validate(List tableInfos) + { + db = mongo.getDB(databaseName); + if (db == null) + { + logger.error("Database " + databaseName + "does not exist"); + throw new SchemaGenerationException("database " + databaseName + "does not exist", "mongoDb", databaseName); + } + else + { + for (TableInfo tableInfo : tableInfos) + { + if (!db.collectionExists(tableInfo.getTableName())) + { + logger.error("Collection " + tableInfo.getTableName() + "does not exist in db " + db.getName()); + throw new SchemaGenerationException("Collection " + tableInfo.getTableName() + + " does not exist in db " + db.getName(), "mongoDb", databaseName, + tableInfo.getTableName()); + } + } + } + } + + /** + * initiate client method initiates the client. + * + * @return boolean value ie client started or not. + * + */ + protected boolean initiateClient() + { + String message = null; + for (String host : hosts) + { + if (host == null || !StringUtils.isNumeric(port) || port.isEmpty()) + { + logger.error("Host or port should not be null / port should be numeric"); + throw new IllegalArgumentException("Host or port should not be null / port should be numeric"); + } + try + { + mongo = new Mongo(host, Integer.parseInt(port)); + db = mongo.getDB(databaseName); + return true; + } + catch (UnknownHostException e) + { + message = e.getMessage(); + logger.error("Database host cannot be resolved, Caused by", e); + } + } + throw new SchemaGenerationException("Database host cannot be resolved, Caused by" + message); + } + + /** + * @param tableInfo + * @return + */ + private DBObject setCollectionProperties(TableInfo tableInfo) + { + boolean isCappedCollection = isCappedCollection(tableInfo); + DBObject options = new BasicDBObject(); + if (isCappedCollection) + { + int collectionSize = MongoDBPropertyReader.msmd != null ? MongoDBPropertyReader.msmd.getCollectionSize( + databaseName, tableInfo.getTableName()) : 100000; + int max = MongoDBPropertyReader.msmd != null ? MongoDBPropertyReader.msmd.getMaxSize(databaseName, + tableInfo.getTableName()) : 100; + options.put(MongoDBConstants.CAPPED, isCappedCollection); + options.put(MongoDBConstants.SIZE, collectionSize); + options.put(MongoDBConstants.MAX, max); + } + return options; + } + + /** + * Checks whether the given table is a capped collection + */ + protected boolean isCappedCollection(TableInfo tableInfo) + { + boolean isCappedCollection = MongoDBPropertyReader.msmd != null ? MongoDBPropertyReader.msmd + .isCappedCollection(databaseName, tableInfo.getTableName()) : false; + return isCappedCollection; + } + + /** + * @param tableInfo + * @param collection + */ + private void createIndexes(TableInfo tableInfo, DBCollection collection) + { + for (IndexInfo indexInfo : tableInfo.getColumnsToBeIndexed()) + { + DBObject keys = new BasicDBObject(); + getIndexType(indexInfo.getIndexType(), keys, indexInfo.getColumnName()); + DBObject options = new BasicDBObject(); + if (indexInfo.getMinValue() != null) + { + options.put(MongoDBConstants.MIN, indexInfo.getMinValue()); + } + if (indexInfo.getMaxValue() != null) + { + options.put(MongoDBConstants.MAX, indexInfo.getMaxValue()); + } + collection.ensureIndex(keys, options); + } + } + + /** + * @param indexType + * @param clazz + * @return + */ + private void getIndexType(String indexType, DBObject keys, String columnName) + { + // TODO validation for indexType and attribute type + + if (indexType != null) + { + if (indexType.equals(IndexType.ASC.name())) + { + keys.put(columnName, 1); + return; + } + else if (indexType.equals(IndexType.DSC.name())) + { + keys.put(columnName, -1); + return; + } + else if (indexType.equals(IndexType.GEO2D.name())) + { + keys.put(columnName, "2d"); + return; + } + } + keys.put(columnName, 1); + return; + } + + /** + * + */ + private void getDBName() + { + List dbs = mongo.getDatabaseNames(); + for (String dbName : dbs) + { + if (dbName.equalsIgnoreCase(databaseName)) + { + databaseName = dbName; + break; + } + } + } + + @Override + public boolean validateEntity(Class clazz) + { + // TODO Auto-generated method stub + return true; + } + +} diff --git a/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/utils/MongoDBUtils.java b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/utils/MongoDBUtils.java new file mode 100644 index 000000000..e4f7dc422 --- /dev/null +++ b/src/kundera-mongo/src/main/java/com/impetus/client/mongodb/utils/MongoDBUtils.java @@ -0,0 +1,109 @@ +/** + * + */ +package com.impetus.client.mongodb.utils; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Date; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EmbeddableType; + +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ReflectUtils; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; + +/** + * @author Kuldeep Mishra + * + */ +public class MongoDBUtils +{ + public static void populateCompoundKey(DBObject dbObj, EntityMetadata m, MetamodelImpl metaModel, Object id) + { + EmbeddableType compoundKey = metaModel.embeddable(m.getIdAttribute().getBindableJavaType()); + // Iterator iter = compoundKey.getAttributes().iterator(); + BasicDBObject compoundKeyObj = new BasicDBObject(); + + compoundKeyObj = getCompoundKeyColumns(m, id, compoundKey); + + dbObj.put("_id", compoundKeyObj); + } + + /** + * @param m + * @param id + * @param compoundKey + * @param compoundKeyObj + */ + public static BasicDBObject getCompoundKeyColumns(EntityMetadata m, Object id, EmbeddableType compoundKey) + { + BasicDBObject compoundKeyObj = new BasicDBObject(); + Field[] fields = m.getIdAttribute().getBindableJavaType().getDeclaredFields(); + + // To ensure order. + for (Field f : fields) + { + if(!ReflectUtils.isTransientOrStatic(f)) + { + Attribute compositeColumn = compoundKey.getAttribute(f.getName()); + + compoundKeyObj.put( + ((AbstractAttribute) compositeColumn).getJPAColumnName(), + populateValue(PropertyAccessorHelper.getObject(id, (Field) compositeColumn.getJavaMember()), + ((AbstractAttribute) compositeColumn).getBindableJavaType())); + } + } + return compoundKeyObj; + } + + /** + * @param valObj + * @return + */ + public static Object populateValue(Object valObj, Class clazz) + { + if (isUTF8Value(clazz) || clazz.isEnum()) + { + return valObj.toString(); + } + else if ((valObj instanceof Calendar) || (valObj instanceof GregorianCalendar)) + { + return ((Calendar) valObj).getTime(); + } + return valObj; + } + + private static boolean isUTF8Value(Class clazz) + { + return (clazz.isAssignableFrom(BigDecimal.class)) + || (clazz.isAssignableFrom(BigInteger.class) || (clazz.isAssignableFrom(String.class))); + } + + /** + * @param value + * @param sourceClass + * @param targetClass + * @return + */ + public static Object getTranslatedObject(Object value, Class sourceClass, Class targetClass) + { + if (sourceClass.isAssignableFrom(Date.class)) + { + value = PropertyAccessorHelper.fromDate(targetClass, sourceClass, value); + } + else + { + value = PropertyAccessorHelper.fromSourceToTargetClass(targetClass, sourceClass, value); + } + return value; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/AppUser.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/AppUser.java new file mode 100644 index 000000000..4aab93dfe --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/AppUser.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "User", schema = "KunderaExamples@mongoTest") +public class AppUser +{ + @Id + private String id; + + @Column + private List tags; + + @Column + private Map propertyKeys; + + @Column + private Set nickNames; + + @Column + protected List friendList; + + @Embedded + private PhoneDirectory phoneDirectory; + + public AppUser() + { + tags = new LinkedList(); + propertyKeys = new HashMap(); + nickNames = new HashSet(); + friendList = new LinkedList(); + tags.add("yo"); + propertyKeys.put("kk", "Kuldeep"); + nickNames.add("kk"); + friendList.add("xamry"); + friendList.add("mevivs"); + } + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public List getTags() + { + return tags; + } + + public Map getPropertyKeys() + { + return propertyKeys; + } + + public Set getNickName() + { + return nickNames; + } + + public List getFriendList() + { + return friendList; + } + + public PhoneDirectory getPhoneDirectory() + { + return phoneDirectory; + } + + public void setPropertyContainer(PhoneDirectory propertyContainer) + { + this.phoneDirectory = propertyContainer; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/BaseTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/BaseTest.java new file mode 100644 index 000000000..94bea84fc --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/BaseTest.java @@ -0,0 +1,296 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import junit.framework.Assert; + +import com.impetus.client.crud.PersonMongo.Month; + +/** + * The Class BaseTest. + * + * @author vivek.mishra + */ +public abstract class BaseTest +{ + /** + * Prepare data. + * + * @param rowKey + * the row key + * @param age + * the age + * @return the person + */ + protected PersonMongo prepareMongoInstance(String rowKey, int age) + { + PersonMongo o = new PersonMongo(); + o.setPersonId(rowKey); + o.setPersonName("vivek"); + o.setAge(age); + o.setDay(Day.FRIDAY); + o.setMonth(Month.JAN); + return o; + } + + /** + * Find by id. + * + * @param + * the element type + * @param clazz + * the clazz + * @param rowKey + * the row key + * @param em + * the em + * @return the e + */ + protected E findById(Class clazz, Object rowKey, EntityManager em) + { + return em.find(clazz, rowKey); + } + + /** + * Assert find by name. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param fieldName + * the field name + */ + protected void assertFindByName(EntityManager em, String clazz, E e, String name, + String fieldName) + { + String query = "Select p from " + clazz + " p where p." + fieldName + " = " + name; + // // find by name. + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert find by name and age. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAge(EntityManager em, String clazz, E e, String name, + String minVal, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find by name and age gt and lt. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeGTAndLT(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // // find by name, age clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + " and p.age > " + + minVal + " and p.age < " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(1, results.size()); + } + + /** + * Assert find by name and age between. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param name + * the name + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByNameAndAgeBetween(EntityManager em, String clazz, E e, String name, + String minVal, String maxVal, String fieldName) + { + // // find by between clause + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + name + + " and p.age between " + minVal + " and " + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + + } + + /** + * Assert find by range. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param minVal + * the min val + * @param maxVal + * the max val + * @param fieldName + * the field name + */ + protected void assertFindByRange(EntityManager em, String clazz, E e, String minVal, + String maxVal, String fieldName) + + { + // find by Range. + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " Between " + minVal + " and " + + maxVal); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + } + + /** + * Assert find without where clause. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + */ + protected void assertFindWithoutWhereClause(EntityManager em, String clazz, E e) + { + // find by without where clause. + Query q = em.createQuery("Select p from " + clazz + " p"); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + } + + /** + * Assert on merge. + * + * @param + * the element type + * @param em + * the em + * @param clazz + * the clazz + * @param e + * the e + * @param oldName + * the old name + * @param newName + * the new name + * @param fieldName + * the field name + */ + protected void assertOnMerge(EntityManager em, String clazz, E e, String oldName, + String newName, String fieldName) + { + Query q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + oldName); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + + q = em.createQuery("Select p from " + clazz + " p where p." + fieldName + " = " + newName); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertNotSame(oldName, getPersonName(e, results.get(0))); + Assert.assertEquals(newName, getPersonName(e, results.get(0))); + } + + /** + * Gets the person name. + * + * @param + * the element type + * @param e + * the e + * @param result + * the result + * @return the person name + */ + private String getPersonName(E e, Object result) + { + return ((PersonMongo) result).getPersonName(); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/CappedCollectionTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/CappedCollectionTest.java new file mode 100644 index 000000000..e2da9a14c --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/CappedCollectionTest.java @@ -0,0 +1,184 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.crud; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.mongodb.MongoDBConstants; +import com.impetus.kundera.client.Client; +import com.mongodb.CommandResult; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBObject; + +/** + * Test case for Capped Collections + * + * @author amresh.singh + */ +public class CappedCollectionTest +{ + private DB db; + + private String persistenceUnit = "mongoSchemaGenerationTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + em.getDelegate(); + getDB(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + truncateMongo(); + emf.close(); + } + + @Test + public void testCappedCollection() + { + // Validate schema + DBCollection collection = db.getCollection("MongoDBCappedEntity"); + Assert.assertTrue(collection.isCapped()); + CommandResult stats = collection.getStats(); + + Object maxObj = stats.get(MongoDBConstants.MAX); + Assert.assertNotNull(maxObj); + int max = Integer.parseInt(maxObj.toString()); + Assert.assertEquals(10, max); + + /* + * Object size = stats.get(MongoDBConstants.SIZE); + * Assert.assertNotNull(size); Assert.assertEquals(10240, + * Integer.parseInt(size.toString())); + */ + + // Index should not have been created + List indexInfo = collection.getIndexInfo(); + Assert.assertTrue(indexInfo.isEmpty() || indexInfo.size() == 1); + + // Insert "Max" records successfully + for (int i = 1; i <= max; i++) + { + MongoDBCappedEntity entity = new MongoDBCappedEntity(); + entity.setPersonId(i + ""); + entity.setPersonName("Person_Name_" + i); + entity.setAge((short) i); + + em.persist(entity); + } + + // Insert one more record and check whether it replaces first one + MongoDBCappedEntity entity = new MongoDBCappedEntity(); + entity.setPersonId((max + 1) + ""); + entity.setPersonName("Person_Name_" + (max + 1)); + entity.setAge((short) (max + 1)); + em.persist(entity); + + em.clear(); + MongoDBCappedEntity firstRecord = em.find(MongoDBCappedEntity.class, "1"); + Assert.assertNull(firstRecord); + + MongoDBCappedEntity lastRecord = em.find(MongoDBCappedEntity.class, "" + (max + 1)); + Assert.assertNotNull(lastRecord); + + // Deleting documents within a capped collection should simply ignore, + // as is done by native API + em.remove(lastRecord); + em.clear(); + lastRecord = em.find(MongoDBCappedEntity.class, "" + (max + 1)); + Assert.assertNotNull(lastRecord); + + } + + private void truncateMongo() + { + + if (db != null) + { + db.dropDatabase(); + } + } + + /** + * + */ + private void getDB() + { + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get(persistenceUnit); + if (client != null) + { + try + { + Field mongodb = client.getClass().getDeclaredField("mongoDb"); + if (!mongodb.isAccessible()) + { + mongodb.setAccessible(true); + } + db = (DB) mongodb.get(client); + } + + catch (SecurityException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (NoSuchFieldException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalArgumentException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalAccessException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/CollecteTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/CollecteTest.java new file mode 100644 index 000000000..01924da33 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/CollecteTest.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.Collecte; +import com.impetus.client.crud.datatypes.entities.Photoo; + +/** + * Junit for https://github.com/impetus-opensource/Kundera/issues/237 + * + * @author vivek.mishra + * + */ +public class CollecteTest +{ + + private static final String _PU = "mongoTest"; + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(_PU); + em = emf.createEntityManager(); + } + + @Test + public void testInsert() + { + // une collecte + Collecte c = new Collecte(); + c.setId("0001"); + c.setEAN("3251248033108"); + c.setIdProduit(123342124L); + c.setDateStatut(new Date()); + c.setStatut(0); + // qq photos + List photos = new ArrayList(); + Photoo p1 = new Photoo(); + p1.setNomPhoto("Photo de Face"); + p1.setMd5("1235847EA873"); + p1.setNomFichier("photo1.jpg"); + photos.add(p1); + Photoo p2 = new Photoo(); + p2.setNomPhoto("Photo composition"); + p2.setMd5("234847EA873"); + p2.setNomFichier("photo2.jpg"); + photos.add(p2); + Photoo p3 = new Photoo(); + p3.setNomPhoto("Photo prix"); + p3.setMd5("5164847EA873"); + p3.setNomFichier("photo3.jpg"); + photos.add(p3); + + c.setPhotos(photos); + em.persist(c); + testSelect(); + + } + + private void testSelect() + { + Query q = em.createQuery("select c from Collecte c where c.id =:id"); + q.setParameter("id", "0001"); + List collectes = q.getResultList(); + Collecte c = collectes.get(0); + Assert.assertEquals(c.getEAN(), "3251248033108"); + Assert.assertEquals(c.getPhotos().size(), 3); + Assert.assertEquals(c.getPhotos().iterator().next().getMd5(), "1235847EA873"); + } + + @After + public void tearDown() + { + em.close(); + emf.close(); + + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/Day.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/Day.java new file mode 100644 index 000000000..80ec989b5 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/Day.java @@ -0,0 +1,6 @@ +package com.impetus.client.crud; + +enum Day +{ + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY; +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/EmbeddableUserTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/EmbeddableUserTest.java new file mode 100644 index 000000000..1c34910c4 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/EmbeddableUserTest.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Embeddable; +import javax.persistence.Entity; +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * EmbeddableUserTest tests @{@link Entity} and {@link Embeddable} having + * {@link Set, List, Map} as its attribute. + * + * @author Kuldeep.Mishra + * + */ +public class EmbeddableUserTest +{ + + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + @Before + public void setUp() + { + emf = Persistence.createEntityManagerFactory("mongoTest"); + em = emf.createEntityManager(); + } + + @Test + public void test() + { + AppUser user = new AppUser(); + user.setId("id"); + PhoneDirectory properties = new PhoneDirectory(); + user.setPropertyContainer(properties); + em.persist(user); + + em.clear(); + + AppUser result = em.find(AppUser.class, "id"); + + Assert.assertNotNull(result); + Assert.assertNotNull(result.getId()); + Assert.assertNotNull(result.getPropertyKeys()); + Assert.assertFalse(result.getPropertyKeys().isEmpty()); + Assert.assertEquals(1, result.getPropertyKeys().size()); + Assert.assertNotNull(result.getNickName()); + Assert.assertFalse(result.getNickName().isEmpty()); + Assert.assertEquals(1, result.getNickName().size()); + Assert.assertTrue(result.getNickName().contains("kk")); + Assert.assertNotNull(result.getFriendList()); + Assert.assertFalse(result.getFriendList().isEmpty()); + Assert.assertEquals(2, result.getFriendList().size()); + Assert.assertNotNull(result.getTags()); + Assert.assertFalse(result.getTags().isEmpty()); + Assert.assertEquals(1, result.getTags().size()); + Assert.assertEquals("yo", result.getTags().get(0)); + + PhoneDirectory propertyContainer = result.getPhoneDirectory(); + Assert.assertNotNull(propertyContainer); + Assert.assertEquals("MyPhoneDirectory", propertyContainer.getPhoneDirectoryName()); + Assert.assertNotNull(propertyContainer.getContactMap()); + Assert.assertFalse(propertyContainer.getContactMap().isEmpty()); + Assert.assertEquals(1, propertyContainer.getContactMap().size()); + Assert.assertEquals("9891991919", propertyContainer.getContactMap().get("xamry")); + Assert.assertNotNull(propertyContainer.getContactNumber()); + Assert.assertFalse(propertyContainer.getContactNumber().isEmpty()); + Assert.assertEquals(1, propertyContainer.getContactNumber().size()); + Assert.assertNotNull(propertyContainer.getContactName()); + Assert.assertFalse(propertyContainer.getContactName().isEmpty()); + Assert.assertEquals(1, propertyContainer.getContactName().size()); + Assert.assertEquals("xamry", propertyContainer.getContactName().get(0)); + + } + + @After + public void tearDown() + { + em.close(); + emf.close(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoAuthenticationTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoAuthenticationTest.java new file mode 100644 index 000000000..6fe16e0cc --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoAuthenticationTest.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.loader.KunderaAuthenticationException; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.mongodb.DB; +import com.mongodb.Mongo; + +/** + * The Class MongoAuthenticationTest. + * + * @author vivek.mishra + */ +public class MongoAuthenticationTest extends BaseTest +{ + private EntityManagerFactory emf; + + private String pu; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + + } + + /** + * Authenticate with valid credentials. + */ + @Test + public void authenticateWithValidCredentials() + { + try + { + pu = "validAuthenticationMongoPu"; + Mongo m = new Mongo(); + String dbname = "KunderaAuthTests"; + String username = "kunderaUser"; + String password = "kunderapassword"; + DB db = m.getDB(dbname); + db.addUser(username, password.toCharArray()); + db.requestDone(); + if (db.authenticate(username, password.toCharArray())) + { + m.close(); + emf = Persistence.createEntityManagerFactory(pu); + Assert.assertNotNull(emf); + EntityManager em = emf.createEntityManager(); + Assert.assertNotNull(em); + } + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + + } + + /** + * Authenticate with invalid credentials. + */ + @Test + public void authenticateWithInValidCredentials() + { + EntityManager em = null; + try + { + pu = "invalidAuthenticationMongoPu"; + emf = Persistence.createEntityManagerFactory(pu); + em = emf.createEntityManager(); + Assert.fail("Shouldn't be called"); + } + catch (KunderaAuthenticationException e) + { + Assert.assertNull(emf); + Assert.assertNull(em); + } + + } + + /** + * No authentication test. + * + */ + @Test + public void noAuthenticationTest() + { + try + { + pu = "mongoTest"; + emf = Persistence.createEntityManagerFactory(pu); + Assert.assertNotNull(emf); + EntityManager em = emf.createEntityManager(); + Assert.assertNotNull(em); + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + // MongoUtils.dropDatabase(emf, pu); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoBatchProcessorTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoBatchProcessorTest.java new file mode 100644 index 000000000..8e086c628 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoBatchProcessorTest.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.utils.MongoUtils; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.persistence.api.Batcher; + +/** + * Batch processing test case for cassandra. + * + * @author vivek.mishra + * + */ +public class MongoBatchProcessorTest +{ + + /** + * persistence unit. + */ + private static final String PERSISTENCE_UNIT = "MongoBatchTest"; + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private List rows; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + em = emf.createEntityManager(); + } + + /** + * Test case for batch operation. + */ + @Test + public void onBatch() + { + int counter = 0; + rows = prepareData(10); + for (PersonBatchMongoEntity entity : rows) + { + em.persist(entity); + + // check for implicit flush. + if (++counter == 5) + { + Map clients = (Map) em.getDelegate(); + + Batcher client = (Batcher) clients.get(PERSISTENCE_UNIT); + Assert.assertEquals(5, client.getBatchSize()); + em.clear(); + for (int i = 0; i < 5; i++) + { + + // assert on each batch size record + Assert.assertNotNull(em.find(PersonBatchMongoEntity.class, rows.get(i).getPersonId())); + + // as batch size is 5. + Assert.assertNull(em.find(PersonBatchMongoEntity.class, rows.get(6).getPersonId())); + } + // means implicit flush must happen + } + } + + // flush all on close. + // explicit flush on close + em.clear(); + em.flush(); + + String sql = " Select p from PersonBatchMongoEntity p"; + Query query = em.createQuery(sql); + List results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(10, results.size()); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (PersonBatchMongoEntity o : rows) + { + em.remove(o); + } + + MongoUtils.dropDatabase(emf, PERSISTENCE_UNIT); + em.close(); + emf.close(); + } + + private List prepareData(Integer noOfRecords) + { + List persons = new ArrayList(); + for (int i = 1; i <= noOfRecords; i++) + { + PersonBatchMongoEntity o = new PersonBatchMongoEntity(); + o.setPersonId(i + ""); + o.setPersonName("vivek" + i); + o.setAge(10); + persons.add(o); + } + + return persons; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBCappedEntity.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBCappedEntity.java new file mode 100644 index 000000000..e15ae1e67 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBCappedEntity.java @@ -0,0 +1,97 @@ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * @author amresh + * + */ +@Entity +@Table(name = "MongoDBCappedEntity", schema = "KunderaMongoSchemaGeneration@mongoSchemaGenerationTest") +@IndexCollection(columns = { @Index(name = "personName", type = "ASC"), + @Index(name = "age", type = "DSC", min = 100, max = 500) }) +public class MongoDBCappedEntity +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBQueryOnIdTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBQueryOnIdTest.java new file mode 100644 index 000000000..981cee035 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/MongoDBQueryOnIdTest.java @@ -0,0 +1,466 @@ +/** + * + */ +package com.impetus.client.crud; + +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.utils.MongoUtils; + +/** + * @author Kuldeep Mishra + * + */ +public class MongoDBQueryOnIdTest extends BaseTest +{ + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private Map col; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("mongoTest"); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + for (Object val : col.values()) + { + em.remove(val); + } + MongoUtils.dropDatabase(emf, "mongoTest"); + em.close(); + emf.close(); + } + + @Test + public void test() + { + init(); + em.clear(); + findById(); + findByWithOutWhereClause(); + findByIdEQ(); + findByIdLT(); + findByIdLTE(); + findByIdGT(); + findByIdGTE(); + findByIdGTEAndLT(); + findByIdGTAndLTE(); + findByIdAndAge(); + findByIdAndAgeGTAndLT(); + findByIdGTAndAgeGTAndLT(); + findByIdGTEAndAge(); + findByIdLTEAndAge(); + } + + /** + * + */ + private void findByWithOutWhereClause() + { + String qry = "Select p.personName from PersonMongo p"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + + } + + /** + * + */ + private void findByIdEQ() + { + String qry = "Select p.personName from PersonMongo p where p.personId = 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonMongo person : persons) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("2", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + + } + + /** + * + */ + private void findByIdLT() + { + String qry = "Select p.personName from PersonMongo p where p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findByIdLTE() + { + String qry = "Select p.personName, p.age from PersonMongo p where p.personId <= 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertEquals(new Integer(20), person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertEquals(new Integer(15), person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGT() + { + String qry = "Select p.personName from PersonMongo p where p.personId > 1"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("3", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findByIdGTE() + { + String qry = "Select p.personName from PersonMongo p where p.personId >= 1 "; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(3, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else if (person.getPersonId().equals("3")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(3, count); + } + + /** + * + */ + private void findByIdGTEAndLT() + { + String qry = "Select p.personName from PersonMongo p where p.personId >= 1 and p.personId < 3"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + + } + + /** + * + */ + private void findByIdGTAndLTE() + { + String qry = "Select p.personName from PersonMongo p where p.personId > 1 and p.personId <= 2"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("2", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + Assert.assertEquals(1, count); + } + + /** + * + */ + private void findByIdGTAndAgeGTAndLT() + { + + String qry = "Select p.personName from PersonMongo p where p.personId > 1 and p.age >=10 and p.age <= 20"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(2, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("2")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + else + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("3", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(2, count); + } + + /** + * + */ + private void findById() + { + PersonMongo personHBase = findById(PersonMongo.class, "1", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(10), personHBase.getAge()); + + personHBase = findById(PersonMongo.class, "2", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(20), personHBase.getAge()); + + personHBase = findById(PersonMongo.class, "3", em); + Assert.assertNotNull(personHBase); + Assert.assertEquals("vivek", personHBase.getPersonName()); + Assert.assertEquals(new Integer(15), personHBase.getAge()); + } + + /** + * + */ + private void findByIdGTEAndAge() + { + String qry = "Select p.personName, p.age from PersonMongo p where p.personId >= 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonMongo person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + } + + /** + * + */ + private void findByIdLTEAndAge() + { + String qry = "Select p.personName, p.age from PersonMongo p where p.personId <= 3 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonMongo person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + } + + } + + /** + * + */ + private void findByIdAndAge() + { + String qry = "Select p.personName, p.age from PersonMongo p where p.personId = 1 and p.age = 10"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + for (PersonMongo person : persons) + { + Assert.assertEquals(new Integer(10), person.getAge()); + Assert.assertEquals("1", person.getPersonId()); + Assert.assertEquals("vivek", person.getPersonName()); + Assert.assertEquals(10, person.getAge().intValue()); + } + } + + /** + * + */ + private void findByIdAndAgeGTAndLT() + { + String qry = "Select p.personName from PersonMongo p where p.personId = 1 and p.personName = vivek and p.age >=10 and p.age <= 20"; + Query q = em.createQuery(qry); + List persons = q.getResultList(); + Assert.assertNotNull(persons); + Assert.assertEquals(1, persons.size()); + int count = 0; + for (PersonMongo person : persons) + { + if (person.getPersonId().equals("1")) + { + Assert.assertNull(person.getAge()); + Assert.assertEquals("vivek", person.getPersonName()); + count++; + } + } + Assert.assertEquals(1, count); + } + + private void init() + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonBatchMongoEntity.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonBatchMongoEntity.java new file mode 100644 index 000000000..f2c744a79 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonBatchMongoEntity.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON_BATCH", schema = "KunderaMongoDataType@MongoBatchTest") +@IndexCollection(columns = { @Index(name = "personName"), @Index(name = "age") }) +public class PersonBatchMongoEntity +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "AGEss") + private byte[] a; + + /** + * @return the a + */ + public byte[] getA() + { + return a; + } + + /** + * @param a + * the a to set + */ + public void setA(byte[] a) + { + this.a = a; + } + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongo.java new file mode 100644 index 000000000..fc8742cd5 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongo.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.NamedQueries; +import javax.persistence.NamedQuery; +import javax.persistence.Table; + +/** + * The Class Person. + */ +@Entity +@Table(name = "PERSON", schema = "KunderaExamples@mongoTest") +@NamedQueries(value = { + @NamedQuery(name = "mongo.named.query", query = "Select p from PersonMongo p where p.personName = :name"), + @NamedQuery(name = "mongo.position.query", query = "Select p from PersonMongo p where p.personName = ?1") }) +public class PersonMongo +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private Integer age; + + @Column(name = "DAY_ENUM") + @Enumerated(EnumType.STRING) + private Day day; + + @Column(name = "MONTH_ENUM") + @Enumerated(EnumType.STRING) + private Month month; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + public void setDay(Day day) + { + this.day = day; + } + + public Day getDay() + { + return day; + } + + public Month getMonth() + { + return month; + } + + public void setMonth(Month month) + { + this.month = month; + } + + enum Month + { + JAN, FEB, MARCH, APRIL, MAY, JUNE; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongoTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongoTest.java new file mode 100644 index 000000000..9ce29f04e --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PersonMongoTest.java @@ -0,0 +1,295 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; +import javax.persistence.TypedQuery; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.PersonMongo.Month; +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.utils.MongoUtils; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +public class PersonMongoTest extends BaseTest +{ + + private static final String _PU = "mongoTest"; + + /** The emf. */ + private static EntityManagerFactory emf; + + /** The em. */ + private static EntityManager em; + + private Map col; + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(_PU); + em = emf.createEntityManager(); + col = new java.util.HashMap(); + } + + /** + * On insert mongo. + */ + @Test + public void onInsertMongo() throws Exception + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + + Query findQuery = em.createQuery("Select p from PersonMongo p"); + List allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p from PersonMongo p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + findQuery = em.createQuery("Select p.age from PersonMongo p where p.personName = vivek"); + allPersons = findQuery.getResultList(); + Assert.assertNotNull(allPersons); + Assert.assertTrue(allPersons.isEmpty()); + + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + em.clear(); + PersonMongo p = findById(PersonMongo.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals(Day.FRIDAY, p.getDay()); + Assert.assertEquals(Month.JAN, p.getMonth()); + Assert.assertEquals("vivek", p.getPersonName()); + assertFindByName(em, "PersonMongo", PersonMongo.class, "vivek", "personName"); + assertFindByNameAndAge(em, "PersonMongo", PersonMongo.class, "vivek", "10", "personName"); + assertFindByNameAndAgeGTAndLT(em, "PersonMongo", PersonMongo.class, "vivek", "10", "20", "personName"); + assertFindByNameAndAgeBetween(em, "PersonMongo", PersonMongo.class, "vivek", "10", "15", "personName"); + assertFindByRange(em, "PersonMongo", PersonMongo.class, "1", "2", "personId"); + assertFindWithoutWhereClause(em, "PersonMongo", PersonMongo.class); + + Query query = em.createNamedQuery("mongo.named.query"); + query.setParameter("name", "vivek"); + List results = query.getResultList(); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(Month.JAN, results.get(0).getMonth()); + + query = em.createNamedQuery("mongo.position.query"); + query.setParameter(1, "vivek"); + results = query.getResultList(); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(Month.JAN, results.get(0).getMonth()); + + query = em.createQuery("select p from PersonMongo p"); + query.setMaxResults(2); + results = query.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + Assert.assertEquals(Month.JAN, results.get(0).getMonth()); + + selectIdQuery(); + + onExecuteScript(); + + } + + private void selectIdQuery() + { + String query = "select p.personId from PersonMongo p"; + Query q = em.createQuery(query); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + Assert.assertNull(results.get(0).getAge()); + + query = "Select p.personId from PersonMongo p where p.personName = vivek"; + // // find by name. + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(3, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + Assert.assertNull(results.get(0).getAge()); + + q = em.createQuery("Select p.personId from PersonMongo p where p.personName = vivek and p.age > " + 10); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertFalse(results.isEmpty()); + Assert.assertEquals(2, results.size()); + Assert.assertNotNull(results.get(0).getPersonId()); + Assert.assertNull(results.get(0).getPersonName()); + Assert.assertNull(results.get(0).getAge()); + } + + /** + * On typed named query. + */ + @Test + public void onNamedTypedQuery() + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + TypedQuery query = em.createNamedQuery("mongo.named.query", PersonMongo.class); + query.setParameter("name", "vivek"); + List results = query.getResultList(); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(Month.JAN, results.get(0).getMonth()); + } + + /** + * On generic typed named query. + */ + @Test + public void onGenericTypedNamedQuery() + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + TypedQuery query = em.createNamedQuery("mongo.named.query", Object.class); + query.setParameter("name", "vivek"); + List results = query.getResultList(); + Assert.assertEquals(3, results.size()); + Assert.assertEquals(PersonMongo.class, results.get(0).getClass()); + } + + /** + * On invalid typed query. + * + */ + @Test + public void onInvalidTypedNamedQuery() + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + + TypedQuery query = null; + try + { + query = em.createNamedQuery("mongo.named.query", PersonBatchMongoEntity.class); + query.setParameter("name", "vivek"); + Assert.fail("Should have gone to catch block, as it is an invalid scenario!"); + } + catch (IllegalArgumentException iaex) + { + Assert.assertNull(query); + } + } + + /** + * On merge mongo. + */ + @Test + public void onMergeMongo() throws Exception + { + Object p1 = prepareMongoInstance("1", 10); + Object p2 = prepareMongoInstance("2", 20); + Object p3 = prepareMongoInstance("3", 15); + em.persist(p1); + em.persist(p2); + em.persist(p3); + col.put("1", p1); + col.put("2", p2); + col.put("3", p3); + PersonMongo p = findById(PersonMongo.class, "1", em); + Assert.assertNotNull(p); + Assert.assertEquals("vivek", p.getPersonName()); + // modify record. + p.setPersonName("newvivek"); + em.merge(p); + assertOnMerge(em, "PersonMongo", PersonMongo.class, "vivek", "newvivek", "personName"); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + {/* + * Delete is working, but as row keys are not deleted from cassandra, so + * resulting in issue while reading back. // Delete + * em.remove(em.find(Person.class, "1")); em.remove(em.find(Person.class, + * "2")); em.remove(em.find(Person.class, "3")); em.close(); emf.close(); + * em = null; emf = null; + */ + for (Object val : col.values()) + { + em.remove(val); + } + MongoUtils.dropDatabase(emf, _PU); + emf.close(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } + + private void onExecuteScript() + { + Map> clients = (Map>) em.getDelegate(); + Client client = clients.get(_PU); + + String jScript = "db.system.js.save({ _id: \"echoFunction\",value : function(x) { return x; }})"; + Object result = ((MongoDBClient) client).executeScript(jScript); + Assert.assertNull(result); + String findOneJScript = "db.PERSON.findOne()"; + result = ((MongoDBClient) client).executeScript(findOneJScript); + Assert.assertNotNull(result); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/PhoneDirectory.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PhoneDirectory.java new file mode 100644 index 000000000..7a3dd0784 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/PhoneDirectory.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class PhoneDirectory +{ + @Column + private String phoneDirectoryName; + + @Column + private List contactName; + + @Column + private Map contactMap; + + @Column + private Set contactNumber; + + public PhoneDirectory() + { + contactName = new LinkedList(); + contactMap = new HashMap(); + contactNumber = new HashSet(); + contactName.add("xamry"); + contactMap.put("xamry", "9891991919"); + contactNumber.add("9891991919"); + phoneDirectoryName = "MyPhoneDirectory"; + } + + public String getPhoneDirectoryName() + { + return phoneDirectoryName; + } + + public List getContactName() + { + return contactName; + } + + public Map getContactMap() + { + return contactMap; + } + + public Set getContactNumber() + { + return contactNumber; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/UserRoleTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/UserRoleTest.java new file mode 100644 index 000000000..3fc11ba4b --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/UserRoleTest.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ + +package com.impetus.client.crud; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.twitter.entities.RoleMongo; +import com.impetus.client.twitter.entities.User; +import com.impetus.client.utils.MongoUtils; + +/** + * The Class UserRoleTest. + */ +public class UserRoleTest +{ + + private EntityManagerFactory emf; + + /** The em. */ + private EntityManager em; + + /** + * Sets the up. + */ + @Before + public void setUp() + { + emf = Persistence.createEntityManagerFactory("mongoTest"); + em = emf.createEntityManager(); + } + + /** + * Test association. + */ + @Test + public void testPersist() + { + RoleMongo rol = new RoleMongo(); + rol.setRolId(1); + rol.setName("Administrador"); + User u = new User(); + u.setAge(15); + u.setEmail("usuario1@infos.com"); + u.setName("usuario1"); + u.setUserId(1); + u.setLastName("apellido1"); + User u2 = new User(); + u2.setAge(17); + u2.setEmail("usuario2@infos.com"); + u2.setName("usuario2"); + u2.setUserId(2); + u2.setLastName("apellido2"); + u.setUserRol(rol); + u2.setUserRol(rol); + List users = new ArrayList(); + users.add(u); + users.add(u2); + rol.setSegUsuarioList(users); + em.persist(rol); + + } + + /** + * Test findby role. + */ + @Test + public void testFindbyRole() + { + testPersist(); + String query = "Select r from RoleMongo r"; + Query q = em.createQuery(query); + List roles = q.getResultList(); + Assert.assertNotNull(roles); + Assert.assertEquals(1, roles.size()); + } + + /** + * Test findby user. + */ + @Test + public void testFindbyUser() + { + testPersist(); + List users = getAllUsers(); + Assert.assertNotNull(users); + Assert.assertEquals(2, users.size()); + } + + /** + * Tear down. + */ + @After + public void tearDown() + { + RoleMongo rol = em.find(RoleMongo.class, 1); + if (rol != null) + { + em.remove(rol); + } + + MongoUtils.dropDatabase(emf, "mongoTest"); + em.close(); + + em = null; + emf.close(); + } + + /** + * @return + */ + private List getAllUsers() + { + String query = "Select u from User u"; + Query q = em.createQuery(query); + List users = q.getResultList(); + return users; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompositeTypeTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompositeTypeTest.java new file mode 100644 index 000000000..b6400f66b --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompositeTypeTest.java @@ -0,0 +1,368 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.lang.reflect.Field; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.mongodb.DB; + +/** + * @author vivek.mishra + * + */ + +public class MongoCompositeTypeTest +{ + private EntityManagerFactory emf; + + private static final Logger logger = LoggerFactory.getLogger(MongoCompositeTypeTest.class); + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + private Date currentDate = new Date(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = null; + emf = Persistence.createEntityManagerFactory("mongoTest"); + } + + /** + * CRUD over Compound primary Key. + */ + @Test + @PerfTest(invocations = 10) + public synchronized void onCRUD() + { + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser user = new MongoPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.close(); // optional,just to clear persistence cache. + + em = emf.createEntityManager(); + MongoPrimeUser result = em.find(MongoPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("my first tweet", result.getTweetBody()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + + em.clear();// optional,just to clear persistence cache. + + user.setTweetBody("After merge"); + em.merge(user); + + em.close();// optional,just to clear persistence cache. + + em = emf.createEntityManager(); + result = em.find(MongoPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("After merge", result.getTweetBody()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + + // deleting composite + em.remove(result); + + em.close();// optional,just to clear persistence cache. + + em = emf.createEntityManager(); + result = em.find(MongoPrimeUser.class, key); + Assert.assertNull(result); + } + + @Test + public synchronized void onQuery() + { + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser user = new MongoPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.close(); // optional,just to clear persistence cache. + em = emf.createEntityManager(); + final String noClause = "Select u from MongoPrimeUser u"; + + final String withFirstCompositeColClause = "Select u from MongoPrimeUser u where u.key.userId = :userId"; + + final String withClauseOnNoncomposite = "Select u from MongoPrimeUser u where u.tweetDate = ?1"; + + // NOSQL Intelligence to teach that query is invalid because partition + // key is not present? + final String withSecondCompositeColClause = "Select u from MongoPrimeUser u where u.key.tweetId = :tweetId"; + final String withBothCompositeColClause = "Select u from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId"; + final String withAllCompositeColClause = "Select u from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + final String withLastCompositeColGTClause = "Select u from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId >= :timeLineId"; + + final String withSelectiveCompositeColClause = "Select u.key from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + + // query over 1 composite and 1 non-column + + // query with no clause. + Query q = em.createQuery(noClause); + List results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withFirstCompositeColClause); + q.setParameter("userId", "mevivs"); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + // Query with composite key clause. + q = em.createQuery(withClauseOnNoncomposite); + q.setParameter(1, currentDate); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withSecondCompositeColClause); + q.setParameter("tweetId", 1); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + // Query with composite key clause. + q = em.createQuery(withBothCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + // Query with composite key clause. + q = em.createQuery(withAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + // Query with composite key clause. + q = em.createQuery(withLastCompositeColGTClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + // TODO:: + // Assert.assertEquals(1, results.size()); + + // Query with composite key with selective clause. + q = em.createQuery(withSelectiveCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertNull(results.get(0).getTweetBody()); + + final String selectiveColumnTweetBodyWithAllCompositeColClause = "Select u.tweetBody from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + // Query for selective column tweetBody with composite key clause. + q = em.createQuery(selectiveColumnTweetBodyWithAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals("my first tweet", results.get(0).getTweetBody()); + Assert.assertNull(results.get(0).getTweetDate()); + + final String selectiveColumnTweetDateWithAllCompositeColClause = "Select u.tweetDate from MongoPrimeUser u where u.key.userId = :userId and u.key.tweetId = :tweetId and u.key.timeLineId = :timeLineId"; + // Query for selective column tweetDate with composite key clause. + q = em.createQuery(selectiveColumnTweetDateWithAllCompositeColClause); + q.setParameter("userId", "mevivs"); + q.setParameter("tweetId", 1); + q.setParameter("timeLineId", timeLineId); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(currentDate.getTime(), results.get(0).getTweetDate().getTime()); + Assert.assertNull(results.get(0).getTweetBody()); + + final String withCompositeKeyClause = "Select u from MongoPrimeUser u where u.key = :key"; + // Query with composite key clause. + q = em.createQuery(withCompositeKeyClause); + q.setParameter("key", key); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + + em.remove(user); + + em.clear();// optional,just to clear persistence cache. + } + + @Test + public synchronized void onNamedQueryTest() + { + updateNamed(); + deleteNamed(); + + } + + /** + * Update by Named Query. + * + * @return + */ + private void updateNamed() + { + EntityManager em = emf.createEntityManager(); + + UUID timeLineId = UUID.randomUUID(); + + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser user = new MongoPrimeUser(key); + user.setTweetBody("my first tweet"); + user.setTweetDate(currentDate); + em.persist(user); + + em.close(); + + em = emf.createEntityManager(); + + String updateQuery = "Update MongoPrimeUser u SET u.tweetBody=after merge where u.tweetBody= :beforeUpdate"; + Query q = em.createQuery(updateQuery); + q.setParameter("beforeUpdate", "my first tweet"); + q.executeUpdate(); + em.close(); + em = emf.createEntityManager(); + + MongoPrimeUser result = em.find(MongoPrimeUser.class, key); + Assert.assertNotNull(result); + Assert.assertEquals("after merge", result.getTweetBody()); + Assert.assertEquals(timeLineId, result.getKey().getTimeLineId()); + Assert.assertEquals(currentDate.getTime(), result.getTweetDate().getTime()); + em.close(); + } + + /** + * delete by Named Query. + */ + private void deleteNamed() + { + UUID timeLineId = UUID.randomUUID(); + + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + + String deleteQuery = "Delete From MongoPrimeUser u where u.tweetBody= :tweetBody"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.setParameter("tweetBody", "after merge"); + q.executeUpdate(); + + em.close(); + em = emf.createEntityManager(); + MongoPrimeUser result = em.find(MongoPrimeUser.class, key); + Assert.assertNull(result); + em.close(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + truncateMongo(); + emf.close(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } + + /** + * + */ + private void truncateMongo() + { + EntityManager em = emf.createEntityManager(); + + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get("mongoTest"); + if (client != null) + { + try + { + Field db = client.getClass().getDeclaredField("mongoDb"); + if (!db.isAccessible()) + { + db.setAccessible(true); + } + DB mongoDB = (DB) db.get(client); + mongoDB.dropDatabase(); + } + catch (SecurityException e) + { + logger.error("Error while truncating database", e); + } + + catch (NoSuchFieldException e) + { + logger.error("Error while truncating database", e); + } + catch (IllegalArgumentException e) + { + logger.error("Error while truncating database", e); + } + catch (IllegalAccessException e) + { + logger.error("Error while truncating database", e); + } + } + + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompoundKey.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompoundKey.java new file mode 100644 index 000000000..0c80f8ae9 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoCompoundKey.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * @author vivek.mishra + */ +@Embeddable +public class MongoCompoundKey +{ + @Column + private String userId; + + @Column + private int tweetId; + + @Column + private UUID timeLineId; + + /** + * + */ + public MongoCompoundKey() + { + } + + /** + * @param userId + * @param tweetId + * @param timeLineId + */ + public MongoCompoundKey(String userId, int tweetId, UUID timeLineId) + { + this.userId = userId; + this.tweetId = tweetId; + this.timeLineId = timeLineId; + } + + /** + * @return the userId + */ + public String getUserId() + { + return userId; + } + + /** + * @return the tweetId + */ + public int getTweetId() + { + return tweetId; + } + + /** + * @return the timeLineId + */ + public UUID getTimeLineId() + { + return timeLineId; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoPrimeUser.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoPrimeUser.java new file mode 100644 index 000000000..2ab576e9d --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/MongoPrimeUser.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "User", schema = "KunderaExamples@mongoTest") +public class MongoPrimeUser +{ + + @EmbeddedId + private MongoCompoundKey key; + + @Column + private String tweetBody; + + @Column + private Date tweetDate; + + public MongoPrimeUser() + { + } + + public MongoPrimeUser(MongoCompoundKey key) + { + this.key = key; + } + + /** + * @return the key + */ + public MongoCompoundKey getKey() + { + return key; + } + + /** + * @return the tweetBody + */ + public String getTweetBody() + { + return tweetBody; + } + + /** + * @return the tweetDate + */ + public Date getTweetDate() + { + return tweetDate; + } + + /** + * @param tweetBody + * the tweetBody to set + */ + public void setTweetBody(String tweetBody) + { + this.tweetBody = tweetBody; + } + + /** + * @param tweetDate + * the tweetDate to set + */ + public void setTweetDate(Date tweetDate) + { + this.tweetDate = tweetDate; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java new file mode 100644 index 000000000..6b8963d85 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfo.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import com.impetus.client.crud.compositeType.MongoPrimeUser; + +/** + * @author vivek.mishra + * + */ + +@Entity +@Table(name = "UserInfo", schema = "KunderaExamples@mongoTest") +public class UserInfo +{ + + @Id + @Column(name = "userInfo_id") + private String userInfoId; + + @Column(name = "first_name") + private String firstName; + + @Column(name = "last_name") + private String lastName; + + @Column(name = "age") + private int age; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinColumn(name = "user_id") + private List timeLine; + + /** + * + */ + public UserInfo() + { + } + + /** + * @param userInfoId + * @param firstName + * @param lastName + * @param age + * @param timeLine + */ + public UserInfo(String userInfoId, String firstName, String lastName, int age, MongoPrimeUser timeLine) + { + super(); + this.userInfoId = userInfoId; + this.firstName = firstName; + this.lastName = lastName; + this.age = age; + if(this.timeLine == null) + { + this.timeLine = new ArrayList(); + } + + this.timeLine.add(timeLine); + } + + /** + * @return the userInfoId + */ + public String getUserInfoId() + { + return userInfoId; + } + + /** + * @return the firstName + */ + public String getFirstName() + { + return firstName; + } + + /** + * @return the lastName + */ + public String getLastName() + { + return lastName; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @return the timeLine + */ + public List getTimeLine() + { + return timeLine; + } + + /** + * @param firstName + * the firstName to set + */ + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java new file mode 100644 index 000000000..20c06528d --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/compositeType/association/UserInfoTest.java @@ -0,0 +1,316 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.compositeType.association; + +import java.lang.reflect.Field; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.crud.compositeType.MongoCompositeTypeTest; +import com.impetus.client.crud.compositeType.MongoCompoundKey; +import com.impetus.client.crud.compositeType.MongoPrimeUser; +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.kundera.client.Client; +import com.mongodb.DB; + +/** + * @author vivek.mishra + * + */ +public class UserInfoTest +{ + + private EntityManagerFactory emf; + + private static final Logger logger = LoggerFactory.getLogger(MongoCompositeTypeTest.class); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("mongoTest"); + } + + @Test + public void onCRUD() + { + EntityManager em = emf.createEntityManager(); + + // Persist + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser timeLine = new MongoPrimeUser(key); + timeLine.setTweetBody("my first tweet"); + timeLine.setTweetDate(currentDate); + + UserInfo userInfo = new UserInfo("mevivs_info", "Vivek", "Mishra", 31, timeLine); + em.persist(userInfo); + em.clear(); + + // Find + UserInfo result = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate, result.getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, result.getTimeLine().get(0).getKey().getTimeLineId()); + Assert.assertEquals("Vivek", result.getFirstName()); + Assert.assertEquals(31, result.getAge()); + + result.setFirstName("Kuldeep"); + result.setAge(23); + + em.merge(result); + + em.clear(); + + // Find + result = null; + result = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate, result.getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, result.getTimeLine().get(0).getKey().getTimeLineId()); + Assert.assertEquals("Kuldeep", result.getFirstName()); + Assert.assertEquals(23, result.getAge()); + + em.remove(result); + + em.clear(); + result = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNull(result); + + } + + @Test + public void onQuery() + { + EntityManager em = emf.createEntityManager(); + + // Persist + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser timeLine = new MongoPrimeUser(key); + timeLine.setTweetBody("my first tweet"); + timeLine.setTweetDate(new Date()); + + UserInfo userInfo = new UserInfo("mevivs_info", "Vivek", "Mishra", 31, timeLine); + em.persist(userInfo); + + em.clear(); // optional,just to clear persistence cache. + final String noClause = "Select u from UserInfo u"; + + final String withClauseOnNoncomposite = "Select u from UserInfo u where u.age = ?1"; + + // NOSQL Intelligence to teach that query is invalid because partition + // key is not present? + final String withAllCompositeColClause = "Select u from UserInfo u where u.userInfoId = :id"; + + // query over 1 composite and 1 non-column + + // query with no clause. + Query q = em.createQuery(noClause); + List results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(31, results.get(0).getAge()); + Assert.assertEquals("Vivek", results.get(0).getFirstName()); + Assert.assertEquals("Mishra", results.get(0).getLastName()); + Assert.assertEquals("mevivs_info", results.get(0).getUserInfoId()); + Assert.assertEquals(currentDate, results.get(0).getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, results.get(0).getTimeLine().get(0).getKey().getTimeLineId()); + + // Query with composite key clause. + q = em.createQuery(withClauseOnNoncomposite); + q.setParameter(1, 31); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(31, results.get(0).getAge()); + Assert.assertEquals("Vivek", results.get(0).getFirstName()); + Assert.assertEquals("Mishra", results.get(0).getLastName()); + Assert.assertEquals("mevivs_info", results.get(0).getUserInfoId()); + Assert.assertEquals(currentDate, results.get(0).getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, results.get(0).getTimeLine().get(0).getKey().getTimeLineId()); + + // Query with composite key clause. + q = em.createQuery(withAllCompositeColClause); + q.setParameter("id", "mevivs_info"); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(31, results.get(0).getAge()); + Assert.assertEquals("Vivek", results.get(0).getFirstName()); + Assert.assertEquals("Mishra", results.get(0).getLastName()); + Assert.assertEquals("mevivs_info", results.get(0).getUserInfoId()); + Assert.assertEquals(currentDate, results.get(0).getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, results.get(0).getTimeLine().get(0).getKey().getTimeLineId()); + + final String selectiveColumnTweetBodyWithAllCompositeColClause = "Select u.firstName from UserInfo u where u.userInfoId = :id"; + // Query with composite key clause. + q = em.createQuery(selectiveColumnTweetBodyWithAllCompositeColClause); + q.setParameter("id", "mevivs_info"); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(0, results.get(0).getAge()); + Assert.assertEquals("Vivek", results.get(0).getFirstName()); + Assert.assertEquals(null, results.get(0).getLastName()); + Assert.assertEquals("mevivs_info", results.get(0).getUserInfoId()); + + final String selectiveColumnTweetDateWithAllCompositeColClause = "Select u.lastName from UserInfo u where u.userInfoId = :id"; + // Query with composite key clause. + q = em.createQuery(selectiveColumnTweetDateWithAllCompositeColClause); + q.setParameter("id", "mevivs_info"); + results = q.getResultList(); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(0, results.get(0).getAge()); + Assert.assertEquals(null, results.get(0).getFirstName()); + Assert.assertEquals("Mishra", results.get(0).getLastName()); + Assert.assertEquals("mevivs_info", results.get(0).getUserInfoId()); + + em.remove(userInfo); + + em.clear();// optional,just to clear persistence cache. + } + + @Test + public void onNamedQueryTest() + { + updateNamed(); + deleteNamed(); + + } + + /** + * @return + */ + private void updateNamed() + { + EntityManager em = emf.createEntityManager(); + + // Persist + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + MongoPrimeUser timeLine = new MongoPrimeUser(key); + timeLine.setTweetBody("my first tweet"); + timeLine.setTweetDate(currentDate); + + UserInfo userInfo = new UserInfo("mevivs_info", "Vivek", "Mishra", 31, timeLine); + em.persist(userInfo); + + em = emf.createEntityManager(); + + String updateQuery = "Update UserInfo u SET u.firstName=Kuldeep where u.firstName= :beforeUpdate"; + Query q = em.createQuery(updateQuery); + q.setParameter("beforeUpdate", "Vivek"); + q.executeUpdate(); + + UserInfo result = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNotNull(result); + Assert.assertEquals(currentDate, result.getTimeLine().get(0).getTweetDate()); + Assert.assertEquals(timeLineId, result.getTimeLine().get(0).getKey().getTimeLineId()); + Assert.assertEquals("Kuldeep", result.getFirstName()); + Assert.assertEquals(31, result.getAge()); + em.close(); + } + + /** + * + */ + private void deleteNamed() + { + UUID timeLineId = UUID.randomUUID(); + Date currentDate = new Date(); + MongoCompoundKey key = new MongoCompoundKey("mevivs", 1, timeLineId); + + String deleteQuery = "Delete From UserInfo u where u.firstName= :firstName"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.setParameter("firstName", "Kuldeep"); + q.executeUpdate(); + + UserInfo result = em.find(UserInfo.class, "mevivs_info"); + Assert.assertNull(result); + em.close(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + truncateMongo(); + emf.close(); + } + + /** + * + */ + private void truncateMongo() + { + EntityManager em = emf.createEntityManager(); + + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get("mongoTest"); + if (client != null) + { + try + { + Field db = client.getClass().getDeclaredField("mongoDb"); + if (!db.isAccessible()) + { + db.setAccessible(true); + } + DB mongoDB = (DB) db.get(client); + mongoDB.dropDatabase(); + } + catch (SecurityException e) + { + logger.error("Error while truncating db",e); + } + + catch (NoSuchFieldException e) + { + logger.error("Error while truncating db",e); + } + catch (IllegalArgumentException e) + { + logger.error("Error while truncating db",e); + } + catch (IllegalAccessException e) + { + logger.error("Error while truncating db",e); + } + } + + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/MongoBase.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/MongoBase.java new file mode 100644 index 000000000..f869f8fb9 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/MongoBase.java @@ -0,0 +1,100 @@ +package com.impetus.client.crud.datatypes; + +import java.lang.reflect.Field; +import java.util.Map; + +import javax.persistence.EntityManager; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.datatypes.datagenerator.DataGenerator; +import com.impetus.kundera.datatypes.datagenerator.DataGeneratorFactory; +import com.mongodb.DB; + +public abstract class MongoBase +{ + public static final boolean RUN_IN_EMBEDDED_MODE = false; + + public static final boolean AUTO_MANAGE_SCHEMA = false; + + protected static final String PERSISTENCE_UNIT = "MongoDataTypeTest"; + + DataGenerator dataGenerator; + + DataGeneratorFactory factory = new DataGeneratorFactory(); + + protected Object getMaxValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.maxValue(); + } + + protected Object getMinValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.minValue(); + } + + protected Object getRandomValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.randomValue(); + } + + protected Object getPartialValue(Class clazz) + { + dataGenerator = factory.getDataGenerator(clazz); + return dataGenerator.partialValue(); + } + + /** + * + */ + protected void truncateMongo(EntityManager em, final String persistenceUnit, final String tableName) + { + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get(persistenceUnit); + if (client != null) + { + try + { + Field db = client.getClass().getDeclaredField("mongoDb"); + if (!db.isAccessible()) + { + db.setAccessible(true); + } + DB mongoDB = (DB) db.get(client); + mongoDB.getCollection(tableName).drop(); + } + catch (SecurityException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (NoSuchFieldException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalArgumentException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalAccessException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + protected abstract void startCluster(); + + protected abstract void stopCluster(); + + protected abstract void createSchema(); + + protected abstract void dropSchema(); +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java new file mode 100644 index 000000000..cac24ba99 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentEntityDef.java @@ -0,0 +1,264 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +/** + * @author vivek.mishra + * + */ +public interface StudentEntityDef +{ + + /** + * @return the studentId + */ + long getStudentId(); + + /** + * @param studentId + * the studentId to set + */ + void setStudentId(long studentId); + + /** + * @return the uniqueId + */ + long getUniqueId(); + + /** + * @param uniqueId + * the uniqueId to set + */ + void setUniqueId(long uniqueId); + + /** + * @return the studentName + */ + String getStudentName(); + + /** + * @param studentName + * the studentName to set + */ + void setStudentName(String studentName); + + /** + * @return the isExceptional + */ + boolean isExceptional(); + + /** + * @param isExceptional + * the isExceptional to set + */ + void setExceptional(boolean isExceptional); + + /** + * @return the age + */ + int getAge(); + + /** + * @param age + * the age to set + */ + void setAge(int age); + + /** + * @return the semester + */ + char getSemester(); + + /** + * @param semester + * the semester to set + */ + void setSemester(char semester); + + /** + * @return the digitalSignature + */ + byte getDigitalSignature(); + + /** + * @param digitalSignature + * the digitalSignature to set + */ + void setDigitalSignature(byte digitalSignature); + + /** + * @return the cgpa + */ + short getCgpa(); + + /** + * @param cgpa + * the cgpa to set + */ + void setCgpa(short cgpa); + + /** + * @return the percentage + */ + float getPercentage(); + + /** + * @param percentage + * the percentage to set + */ + void setPercentage(float percentage); + + /** + * @return the height + */ + double getHeight(); + + /** + * @param height + * the height to set + */ + void setHeight(double height); + + /** + * @return the enrolmentDate + */ + java.util.Date getEnrolmentDate(); + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + void setEnrolmentDate(java.util.Date enrolmentDate); + + /** + * @return the enrolmentTime + */ + java.util.Date getEnrolmentTime(); + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + void setEnrolmentTime(java.util.Date enrolmentTime); + + /** + * @return the joiningDateAndTime + */ + java.util.Date getJoiningDateAndTime(); + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + void setJoiningDateAndTime(java.util.Date joiningDateAndTime); + + /** + * @return the yearsSpent + */ + Integer getYearsSpent(); + + /** + * @param yearsSpent + * the yearsSpent to set + */ + void setYearsSpent(Integer yearsSpent); + + /** + * @return the rollNumber + */ + Long getRollNumber(); + + /** + * @param rollNumber + * the rollNumber to set + */ + void setRollNumber(Long rollNumber); + + /** + * @return the monthlyFee + */ + Double getMonthlyFee(); + + /** + * @param monthlyFee + * the monthlyFee to set + */ + void setMonthlyFee(Double monthlyFee); + + java.sql.Date getSqlDate(); + + void setSqlDate(java.sql.Date sqlDate); + + /** + * @return the sqlTimestamp + */ + java.sql.Timestamp getSqlTimestamp(); + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + void setSqlTimestamp(java.sql.Timestamp sqlTimestamp); + + /** + * @return the sqlTime + */ + java.sql.Time getSqlTime(); + + /** + * @param sqlTime + * the sqlTime to set + */ + void setSqlTime(java.sql.Time sqlTime); + + /** + * @return the bigInteger + */ + BigInteger getBigInteger(); + + /** + * @param bigInteger + * the bigInteger to set + */ + void setBigInteger(BigInteger bigInteger); + + /** + * @return the bigDecimal + */ + BigDecimal getBigDecimal(); + + /** + * @param bigDecimal + * the bigDecimal to set + */ + void setBigDecimal(BigDecimal bigDecimal); + + /** + * @return the calendar + */ + Calendar getCalendar(); + + /** + * @param calendar + * the calendar to set + */ + void setCalendar(Calendar calendar); + +} \ No newline at end of file diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongo.java new file mode 100644 index 000000000..aed9774fe --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongo.java @@ -0,0 +1,478 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +@Entity +@Table(name = "STUDENT", schema = "KunderaExamples@mongoTest") +@IndexCollection(columns = { @Index(name = "uniqueId"), @Index(name = "studentName"), @Index(name = "age") }) +public class StudentMongo implements StudentEntityDef +{ + // Primitive Types + @Id + @Column(name = "STUDENT_ID") + private long studentId; + + @Column(name = "UNIQUE_ID") + private long uniqueId; + + @Column(name = "STUDENT_NAME") + private String studentName; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "AGE") + private int age; + + @Column(name = "SEMESTER") + private char semester; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "CGPA") + private short cgpa; // 1-10 + + @Column(name = "PERCENTAGE") + private float percentage; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "ROLL_NUMBER") + private Long rollNumber; + + @Column(name = "MONTHLY_FEE") + private Double monthlyFee; + + @Column(name = "SQL_DATE") + private java.sql.Date sqlDate; + + @Column(name = "SQL_TIMESTAMP") + private java.sql.Timestamp sqlTimestamp; + + @Column(name = "SQL_TIME") + private java.sql.Time sqlTime; + + @Column(name = "BIG_INT") + private BigInteger bigInteger; + + @Column(name = "BIG_DECIMAL") + private BigDecimal bigDecimal; + + @Column(name = "CALENDAR") + private Calendar calendar; + + /** + * @return the studentId + */ + public long getStudentId() + { + return studentId; + } + + /** + * @param studentId + * the studentId to set + */ + public void setStudentId(long studentId) + { + this.studentId = studentId; + } + + /** + * @return the uniqueId + */ + public long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the studentName + */ + public String getStudentName() + { + return studentName; + } + + /** + * @param studentName + * the studentName to set + */ + public void setStudentName(String studentName) + { + this.studentName = studentName; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the semester + */ + public char getSemester() + { + return semester; + } + + /** + * @param semester + * the semester to set + */ + public void setSemester(char semester) + { + this.semester = semester; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the cgpa + */ + public short getCgpa() + { + return cgpa; + } + + /** + * @param cgpa + * the cgpa to set + */ + public void setCgpa(short cgpa) + { + this.cgpa = cgpa; + } + + /** + * @return the percentage + */ + public float getPercentage() + { + return percentage; + } + + /** + * @param percentage + * the percentage to set + */ + public void setPercentage(float percentage) + { + this.percentage = percentage; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the rollNumber + */ + public Long getRollNumber() + { + return rollNumber; + } + + /** + * @param rollNumber + * the rollNumber to set + */ + public void setRollNumber(Long rollNumber) + { + this.rollNumber = rollNumber; + } + + /** + * @return the monthlyFee + */ + public Double getMonthlyFee() + { + return monthlyFee; + } + + /** + * @param monthlyFee + * the monthlyFee to set + */ + public void setMonthlyFee(Double monthlyFee) + { + this.monthlyFee = monthlyFee; + } + + public java.sql.Date getSqlDate() + { + return sqlDate; + } + + public void setSqlDate(java.sql.Date sqlDate) + { + this.sqlDate = sqlDate; + } + + /** + * @return the sqlTimestamp + */ + public java.sql.Timestamp getSqlTimestamp() + { + return sqlTimestamp; + } + + /** + * @param sqlTimestamp + * the sqlTimestamp to set + */ + public void setSqlTimestamp(java.sql.Timestamp sqlTimestamp) + { + this.sqlTimestamp = sqlTimestamp; + } + + /** + * @return the sqlTime + */ + public java.sql.Time getSqlTime() + { + return sqlTime; + } + + /** + * @param sqlTime + * the sqlTime to set + */ + public void setSqlTime(java.sql.Time sqlTime) + { + this.sqlTime = sqlTime; + } + + /** + * @return the bigInteger + */ + public BigInteger getBigInteger() + { + return bigInteger; + } + + /** + * @param bigInteger + * the bigInteger to set + */ + public void setBigInteger(BigInteger bigInteger) + { + this.bigInteger = bigInteger; + } + + /** + * @return the bigDecimal + */ + public BigDecimal getBigDecimal() + { + return bigDecimal; + } + + /** + * @param bigDecimal + * the bigDecimal to set + */ + public void setBigDecimal(BigDecimal bigDecimal) + { + this.bigDecimal = bigDecimal; + } + + /** + * @return the calendar + */ + public Calendar getCalendar() + { + return calendar; + } + + /** + * @param calendar + * the calendar to set + */ + public void setCalendar(Calendar calendar) + { + this.calendar = calendar; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBase.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBase.java new file mode 100644 index 000000000..24f2405ad --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBase.java @@ -0,0 +1,348 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import com.impetus.client.crud.BaseTest; +import com.impetus.kundera.metadata.model.KunderaMetadata; + +/** + * The Class StudentBase. + * + * @param + * the element type + */ +public abstract class StudentMongoBase extends BaseTest +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + /** The emf. */ + protected EntityManagerFactory emf; + + /** The em. */ + protected EntityManager em; + + // protected String persistenceUnit = + // /*"twissandra,twibase,twingo,picmysql"*/null; + + /** The student id1. */ + protected Object studentId1; + + /** The student id2. */ + protected Object studentId2; + + /** The student id3. */ + protected Object studentId3; + + /** The enrolment date. */ + protected Date enrolmentDate = new Date(); + + /** The joining date and time. */ + protected Date joiningDateAndTime = new Date(); + + /** The date. */ + protected long date = new Date().getTime(); + + /** The new sql date. */ + protected java.sql.Date newSqlDate = new java.sql.Date(date); + + /** The enrolment time. */ + protected Date enrolmentTime = new Date(); + + /** The sql time. */ + protected java.sql.Time sqlTime = new java.sql.Time(date); + + /** The sql timestamp. */ + protected java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(date); + + /** The big decimal. */ + protected BigDecimal bigDecimal = new BigDecimal(123456789); + + /** The big integer. */ + protected BigInteger bigInteger = new BigInteger("123456789"); + + /** The number of students. */ + protected int numberOfStudents = 1000; + + /** The calendar. */ + protected Calendar calendar = Calendar.getInstance(); + + /** The dao. */ + // StudentDao dao; + + /** + * Sets the up internal. + * + * @param persisntenceUnit + * the new up internal + */ + protected void setupInternal(String persisntenceUnit) + { + // dao = new StudentDao(persistenceUnit); + + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + + studentId1 = new Long(12345677); + studentId2 = new Long(12345678); + studentId3 = new Long(12345679); + + emf = Persistence.createEntityManagerFactory(persisntenceUnit); + em = emf.createEntityManager(); + } + + /** + * Sets the up internal. + * + * @param persistenceUnit + * the new up internal + */ + protected void teardownInternal(String persistenceUnit) + { + + if (RUN_IN_EMBEDDED_MODE) + { + stopServer(); + } + + if (AUTO_MANAGE_SCHEMA) + { + deleteSchema(); + } + if (emf != null) + { + emf.close(); + } + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + } + + /** + * on insert. + * + * @param instance + * the instance + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + */ + protected void onInsert(E instance) throws InstantiationException, IllegalAccessException + { + + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", false, 10, 'A', (byte) 5, (short) 8, + (float) 61.6, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId2, 78575785898L, "Amresh", true, 20, 'C', (byte) 50, (short) 8, + (float) 69.6, 163.76765655, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, new BigInteger( + "1234567810"), calendar, ((E) instance.getClass().newInstance()))); + + em.persist(prepareData((Long) studentId3, 78575785899L, "Amresh", true, 15, 'C', (byte) 50, (short) 8, + (float) 69.6, 163.76765656, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, new BigInteger( + "1234567811"), calendar, ((E) instance.getClass().newInstance()))); + + } + + /** + * Prepare data. + * + * @param studentId + * the student id + * @param uniqueId + * the unique id + * @param studentName + * the student name + * @param isExceptional + * the is exceptional + * @param age + * the age + * @param semester + * the semester + * @param digitalSignature + * the digital signature + * @param cgpa + * the cgpa + * @param percentage + * the percentage + * @param height + * the height + * @param enrolmentDate + * the enrolment date + * @param enrolmentTime + * the enrolment time + * @param joiningDateAndTime + * the joining date and time + * @param yearsSpent + * the years spent + * @param rollNumber + * the roll number + * @param monthlyFee + * the monthly fee + * @param newSqlDate + * the new sql date + * @param sqlTime + * the sql time + * @param sqlTimestamp + * the sql timestamp + * @param bigDecimal + * the big decimal + * @param bigInteger + * the big integer + * @param calendar + * the calendar + * @param o + * the o + * @return the person + */ + protected E prepareData(long studentId, long uniqueId, String studentName, boolean isExceptional, int age, + char semester, byte digitalSignature, short cgpa, float percentage, double height, + java.util.Date enrolmentDate, java.util.Date enrolmentTime, java.util.Date joiningDateAndTime, + Integer yearsSpent, Long rollNumber, Double monthlyFee, java.sql.Date newSqlDate, java.sql.Time sqlTime, + java.sql.Timestamp sqlTimestamp, BigDecimal bigDecimal, BigInteger bigInteger, Calendar calendar, E o) + { + o.setStudentId((Long) studentId); + o.setUniqueId(uniqueId); + o.setStudentName(studentName); + o.setExceptional(isExceptional); + o.setAge(age); + o.setSemester(semester); + o.setDigitalSignature(digitalSignature); + o.setCgpa(cgpa); + o.setPercentage(percentage); + o.setHeight(height); + + o.setEnrolmentDate(enrolmentDate); + o.setEnrolmentTime(enrolmentTime); + o.setJoiningDateAndTime(joiningDateAndTime); + + o.setYearsSpent(yearsSpent); + o.setRollNumber(rollNumber); + o.setMonthlyFee(monthlyFee); + o.setSqlDate(newSqlDate); + o.setSqlTime(sqlTime); + o.setSqlTimestamp(sqlTimestamp); + o.setBigDecimal(bigDecimal); + o.setBigInteger(bigInteger); + o.setCalendar(calendar); + return (E) o; + } + + /** + * Assert on data types. + * + * @param s + * the s + */ + protected void assertOnDataTypes(E s) + { + + Assert.assertNotNull(s); + Assert.assertEquals(((Long) studentId1).longValue(), s.getStudentId()); + Assert.assertEquals(78575785897L, s.getUniqueId()); + Assert.assertEquals("Amresh", s.getStudentName()); + Assert.assertEquals(false, s.isExceptional()); + Assert.assertEquals(10, s.getAge()); + Assert.assertEquals('A', s.getSemester()); + Assert.assertEquals((byte) 5, s.getDigitalSignature()); + Assert.assertEquals((short) 8, s.getCgpa()); + Assert.assertEquals((float) 61.6, s.getPercentage()); + Assert.assertEquals(163.76765654, s.getHeight()); + + Assert.assertEquals(enrolmentDate.getDate(), s.getEnrolmentDate().getDate()); + Assert.assertEquals(enrolmentDate.getMonth(), s.getEnrolmentDate().getMonth()); + Assert.assertEquals(enrolmentDate.getYear(), s.getEnrolmentDate().getYear()); + + Assert.assertEquals(enrolmentTime.getHours(), s.getEnrolmentTime().getHours()); + Assert.assertEquals(enrolmentTime.getMinutes(), s.getEnrolmentTime().getMinutes()); + Assert.assertEquals(enrolmentTime.getSeconds(), s.getEnrolmentTime().getSeconds()); + + Assert.assertEquals(joiningDateAndTime.getDate(), s.getJoiningDateAndTime().getDate()); + Assert.assertEquals(joiningDateAndTime.getMonth(), s.getJoiningDateAndTime().getMonth()); + Assert.assertEquals(joiningDateAndTime.getYear(), s.getJoiningDateAndTime().getYear()); + Assert.assertEquals(joiningDateAndTime.getHours(), s.getJoiningDateAndTime().getHours()); + Assert.assertEquals(joiningDateAndTime.getMinutes(), s.getJoiningDateAndTime().getMinutes()); + Assert.assertEquals(joiningDateAndTime.getSeconds(), s.getJoiningDateAndTime().getSeconds()); + + Assert.assertEquals(newSqlDate.getDate(), s.getSqlDate().getDate()); + Assert.assertEquals(newSqlDate.getMonth(), s.getSqlDate().getMonth()); + Assert.assertEquals(newSqlDate.getYear(), s.getSqlDate().getYear()); + + Assert.assertEquals(sqlTime.getMinutes(), s.getSqlTime().getMinutes()); + Assert.assertEquals(sqlTime.getSeconds(), s.getSqlTime().getSeconds()); + Assert.assertEquals(sqlTime.getHours(), s.getSqlTime().getHours()); + + Assert.assertEquals(sqlTimestamp.getDate(), s.getSqlTimestamp().getDate()); + Assert.assertEquals(sqlTimestamp.getMonth(), s.getSqlTimestamp().getMonth()); + Assert.assertEquals(sqlTimestamp.getYear(), s.getSqlTimestamp().getYear()); + Assert.assertEquals(sqlTimestamp.getHours(), s.getSqlTimestamp().getHours()); + Assert.assertEquals(sqlTimestamp.getMinutes(), s.getSqlTimestamp().getMinutes()); + Assert.assertEquals(sqlTimestamp.getSeconds(), s.getSqlTimestamp().getSeconds()); + + Assert.assertEquals(Math.round(bigDecimal.doubleValue()), Math.round(s.getBigDecimal().doubleValue())); + Assert.assertEquals(bigInteger, s.getBigInteger()); + + Assert.assertEquals(calendar.get(Calendar.YEAR), s.getCalendar().get(Calendar.YEAR)); + Assert.assertEquals(calendar.get(Calendar.MONTH), s.getCalendar().get(Calendar.MONTH)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_YEAR), s.getCalendar().get(Calendar.WEEK_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.WEEK_OF_MONTH), s.getCalendar().get(Calendar.WEEK_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_MONTH), s.getCalendar().get(Calendar.DAY_OF_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK), s.getCalendar().get(Calendar.DAY_OF_WEEK)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH), + s.getCalendar().get(Calendar.DAY_OF_WEEK_IN_MONTH)); + Assert.assertEquals(calendar.get(Calendar.DAY_OF_YEAR), s.getCalendar().get(Calendar.DAY_OF_YEAR)); + Assert.assertEquals(calendar.get(Calendar.HOUR), s.getCalendar().get(Calendar.HOUR)); + Assert.assertEquals(calendar.get(Calendar.HOUR_OF_DAY), s.getCalendar().get(Calendar.HOUR_OF_DAY)); + Assert.assertEquals(calendar.get(Calendar.AM), s.getCalendar().get(Calendar.AM)); + Assert.assertEquals(calendar.get(Calendar.PM), s.getCalendar().get(Calendar.PM)); + Assert.assertEquals(calendar.get(Calendar.AM_PM), s.getCalendar().get(Calendar.AM_PM)); + + Assert.assertEquals(new Integer(3), s.getYearsSpent()); + Assert.assertEquals(new Long(978423946455l), s.getRollNumber()); + Assert.assertEquals(new Double(135434.89), s.getMonthlyFee()); + + } + + abstract void startServer(); + + abstract void stopServer(); + + abstract void createSchema(); + + abstract void deleteSchema(); + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigDecimalTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigDecimalTest.java new file mode 100644 index 000000000..43ec6a200 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigDecimalTest.java @@ -0,0 +1,565 @@ +package com.impetus.client.crud.datatypes; + +import java.math.BigDecimal; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoBigDecimal; + +public class StudentMongoBigDecimalTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + em.remove(em.find(StudentMongoBigDecimal.class, getMinValue(BigDecimal.class))); + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigDecimal + StudentMongoBigDecimal studentMax = new StudentMongoBigDecimal(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigDecimal) getMaxValue(BigDecimal.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigDecimal + StudentMongoBigDecimal studentMin = new StudentMongoBigDecimal(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((BigDecimal) getMinValue(BigDecimal.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigDecimal + StudentMongoBigDecimal student = new StudentMongoBigDecimal(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigDecimal) getRandomValue(BigDecimal.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBigDecimal studentMax = em.find(StudentMongoBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigDecimal studentMin = em.find(StudentMongoBigDecimal.class, getMinValue(BigDecimal.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigDecimal student = em.find(StudentMongoBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoBigDecimal student = em.find(StudentMongoBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigDecimal newStudent = em.find(StudentMongoBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.age = ?1 and s.name > Amresh and s.name <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(String.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(BigDecimal.class)); + q.setParameter(2, getMaxValue(BigDecimal.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Kuldeep and s.age > ?1"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Kuldeep and s.age > ?1 and s.age <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getMaxValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBigDecimal studentMax = em.find(StudentMongoBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoBigDecimal.class, getMaxValue(BigDecimal.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoBigDecimal s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigDecimal newStudent = em.find(StudentMongoBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoBigDecimal s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigDecimal newStudent = em.find(StudentMongoBigDecimal.class, getRandomValue(BigDecimal.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Amresh and s.age between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Amresh and s.age > ?1 and s.age < ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Kuldeep and s.age >= ?1 and s.age <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.age = ?1"; + q = em.createQuery(query); + q.setParameter(1, getRandomValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigDecimal s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoBigDecimal s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoBigDecimal student : students) + { + if (student.getId().equals(getMaxValue(BigDecimal.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigDecimal.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigDecimal.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigIntegerTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigIntegerTest.java new file mode 100644 index 000000000..63178b7aa --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBigIntegerTest.java @@ -0,0 +1,578 @@ +package com.impetus.client.crud.datatypes; + +import java.math.BigInteger; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoBigInteger; + +public class StudentMongoBigIntegerTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + } + + @After + public void tearDown() throws Exception + { + // EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoBigInteger.class, + // getMinValue(BigInteger.class))); + // if (AUTO_MANAGE_SCHEMA) + // { + dropSchema(); + // } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of BigInteger + StudentMongoBigInteger studentMax = new StudentMongoBigInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((BigInteger) getMaxValue(BigInteger.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of BigInteger + StudentMongoBigInteger studentMin = new StudentMongoBigInteger(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((BigInteger) getMinValue(BigInteger.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of BigInteger + StudentMongoBigInteger student = new StudentMongoBigInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((BigInteger) getRandomValue(BigInteger.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBigInteger studentMax = em.find(StudentMongoBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigInteger studentMin = em.find(StudentMongoBigInteger.class, getMinValue(BigInteger.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigInteger student = em.find(StudentMongoBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoBigInteger student = em.find(StudentMongoBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigInteger newStudent = em.find(StudentMongoBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.age = ?1 and s.name > Amresh and s.name <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(String.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(BigInteger.class)); + q.setParameter(2, getMaxValue(BigInteger.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Kuldeep and s.age > ?1"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Kuldeep and s.age > ?1 and s.age <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getMaxValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBigInteger studentMax = em.find(StudentMongoBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoBigInteger.class, getMaxValue(BigInteger.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoBigInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigInteger newStudent = em.find(StudentMongoBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoBigInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBigInteger newStudent = em.find(StudentMongoBigInteger.class, getRandomValue(BigInteger.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Amresh and s.age between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Amresh and s.age > ?1 and s.age < ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Kuldeep and s.age >= ?1 and s.age <= ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.age = ?1"; + q = em.createQuery(query); + q.setParameter(1, getRandomValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBigInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(BigInteger.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoBigInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoBigInteger student : students) + { + if (student.getId().equals(getMaxValue(BigInteger.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(BigInteger.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(BigInteger.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + EntityManager em = emf.createEntityManager(); + truncateMongo(em, PERSISTENCE_UNIT, "StudentMongoBigInteger"); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanPrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanPrimitiveTest.java new file mode 100644 index 000000000..ef1d73e59 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanPrimitiveTest.java @@ -0,0 +1,550 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoBooleanPrimitive; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentMongoBooleanPrimitiveTest extends MongoBase +{ + + /** + * + */ + private static final String _PERSISTENCEUNIT = "MongoDataTypeTest"; + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory(_PERSISTENCEUNIT); + } + + @After + public void tearDown() throws Exception + { + dropSchema(); + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of boolean + StudentMongoBooleanPrimitive studentMax = new StudentMongoBooleanPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of boolean + StudentMongoBooleanPrimitive studentMin = new StudentMongoBooleanPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Boolean) getMinValue(boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBooleanPrimitive studentMax = em.find(StudentMongoBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanPrimitive studentMin = em.find(StudentMongoBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoBooleanPrimitive student = em.find(StudentMongoBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanPrimitive newStudent = em.find(StudentMongoBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(boolean.class)); + q.setParameter(2, getMaxValue(boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Kuldeep or s.age > " + getMinValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for Mongo", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + Assert.assertEquals(getMaxValue(boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBooleanPrimitive studentMax = em.find(StudentMongoBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMinValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoBooleanPrimitive.class, getMinValue(boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoBooleanPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanPrimitive newStudent = em.find(StudentMongoBooleanPrimitive.class, getRandomValue(boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoBooleanPrimitive s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanPrimitive newStudent = em.find(StudentMongoBooleanPrimitive.class, getMaxValue(boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Kuldeep and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.age = " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoBooleanPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanPrimitive student : students) + { + if (student.getId() == ((Boolean) getMaxValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + EntityManager em = emf.createEntityManager(); + truncateMongo(em, _PERSISTENCEUNIT, "StudentMongoBooleanPrimitive"); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanWrapperTest.java new file mode 100644 index 000000000..2fa4b5dbf --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBooleanWrapperTest.java @@ -0,0 +1,550 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoBooleanWrapper; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentMongoBooleanWrapperTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + // EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoBooleanWrapper.class, + // getMinValue(Boolean.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Boolean + StudentMongoBooleanWrapper studentMax = new StudentMongoBooleanWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Boolean) getMaxValue(Boolean.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Boolean + StudentMongoBooleanWrapper studentMin = new StudentMongoBooleanWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Boolean) getMinValue(Boolean.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBooleanWrapper studentMax = em.find(StudentMongoBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanWrapper studentMin = em.find(StudentMongoBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + em.close(); + } + + public void testMerge(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoBooleanWrapper student = em.find(StudentMongoBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanWrapper newStudent = em.find(StudentMongoBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(Boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Boolean.class)); + q.setParameter(2, getMaxValue(Boolean.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Kuldeep or s.age > " + getMinValue(short.class); + try + { + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for Mongo", qhe.getMessage()); + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + Assert.assertEquals(getMaxValue(Boolean.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(Boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(Boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBooleanWrapper studentMax = em.find(StudentMongoBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMinValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoBooleanWrapper.class, getMinValue(Boolean.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(Boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoBooleanWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanWrapper newStudent = em.find(StudentMongoBooleanWrapper.class, getRandomValue(Boolean.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(Boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoBooleanWrapper s SET s.name=Vivek where s.id=true"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBooleanWrapper newStudent = em.find(StudentMongoBooleanWrapper.class, getMaxValue(Boolean.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Kuldeep and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanWrapper student : students) + { + if (student.getId() == ((Boolean) getMaxValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Boolean) getMinValue(Boolean.class)).booleanValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.age = " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBooleanWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Boolean.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoBooleanWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoBooleanWrapper student : students) + { + if (student.getId().equals(getMaxValue(Boolean.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Boolean.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBytePrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBytePrimitiveTest.java new file mode 100644 index 000000000..ec5f319e6 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoBytePrimitiveTest.java @@ -0,0 +1,575 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoBytePrimitive; + +public class StudentMongoBytePrimitiveTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class))); + em.remove(em.find(StudentMongoBytePrimitive.class, getMinValue(byte.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of byte + StudentMongoBytePrimitive studentMax = new StudentMongoBytePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of byte + StudentMongoBytePrimitive studentMin = new StudentMongoBytePrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Byte) getMinValue(byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of byte + StudentMongoBytePrimitive student = new StudentMongoBytePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBytePrimitive studentMax = em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBytePrimitive studentMin = em.find(StudentMongoBytePrimitive.class, getMinValue(byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBytePrimitive student = em.find(StudentMongoBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoBytePrimitive student = em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBytePrimitive newStudent = em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(byte.class)); + q.setParameter(2, getMaxValue(byte.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Byte) getMinValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getMaxValue(byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoBytePrimitive studentMax = em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoBytePrimitive.class, getMaxValue(byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoBytePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBytePrimitive newStudent = em.find(StudentMongoBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoBytePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoBytePrimitive newStudent = em.find(StudentMongoBytePrimitive.class, getRandomValue(byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoBytePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoBytePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoBytePrimitive student : students) + { + if (student.getId() == ((Byte) getMaxValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Byte) getMinValue(byte.class)).byteValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoByteWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoByteWrapperTest.java new file mode 100644 index 000000000..ad1dd3e39 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoByteWrapperTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoByteWrapper; + +public class StudentMongoByteWrapperTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class))); + em.remove(em.find(StudentMongoByteWrapper.class, getMinValue(Byte.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Byte + StudentMongoByteWrapper studentMax = new StudentMongoByteWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Byte) getMaxValue(Byte.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Byte + StudentMongoByteWrapper studentMin = new StudentMongoByteWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Byte) getMinValue(Byte.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Byte + StudentMongoByteWrapper student = new StudentMongoByteWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Byte) getRandomValue(Byte.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoByteWrapper studentMax = em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoByteWrapper studentMin = em.find(StudentMongoByteWrapper.class, getMinValue(Byte.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoByteWrapper student = em.find(StudentMongoByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoByteWrapper student = em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoByteWrapper newStudent = em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Byte.class)); + q.setParameter(2, getMaxValue(Byte.class)); + + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Byte.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getMaxValue(Byte.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoByteWrapper studentMax = em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoByteWrapper.class, getMaxValue(Byte.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoByteWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoByteWrapper newStudent = em.find(StudentMongoByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoByteWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoByteWrapper newStudent = em.find(StudentMongoByteWrapper.class, getRandomValue(Byte.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoByteWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Byte.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoByteWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoByteWrapper student : students) + { + if (student.getId().equals(getMaxValue(Byte.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Byte.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Byte.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCalendarTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCalendarTest.java new file mode 100644 index 000000000..27fbc2ad2 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCalendarTest.java @@ -0,0 +1,494 @@ +package com.impetus.client.crud.datatypes; + +import java.util.Calendar; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoCalendar; +import com.impetus.client.utils.MongoUtils; +import com.impetus.kundera.query.QueryHandlerException; + +public class StudentMongoCalendarTest extends MongoBase +{ + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + MongoUtils.dropDatabase(emf, "MongoDataTypeTest"); + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Calendar + StudentMongoCalendar studentMax = new StudentMongoCalendar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId(((Calendar) getMaxValue(Calendar.class))); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoCalendar studentMax = em.find(StudentMongoCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoCalendar student = em.find(StudentMongoCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCalendar newStudent = em.find(StudentMongoCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.age = " + getMaxValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.id between " + getRandomValue(Calendar.class) + " and " + + getMaxValue(Calendar.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoCalendar student : students) + { + if (student.getId().equals(getRandomValue(Calendar.class))) + { + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Calendar.class))) + { + Assert.assertEquals(getPartialValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em = null; + String query; + Query q; + try + { + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + } + catch (QueryHandlerException qhe) + { + Assert.assertEquals("unsupported clause OR for Hbase", qhe.getMessage()); + } + finally + { + if (em != null) + { + em.close(); + } + } + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Calendar + StudentMongoCalendar studentMax = new StudentMongoCalendar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId(((Calendar) getMaxValue(Calendar.class))); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + em.close(); + + em = emf.createEntityManager(); + + studentMax = em.find(StudentMongoCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoCalendar.class, getMaxValue(Calendar.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoCalendar s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCalendar newStudent = em.find(StudentMongoCalendar.class, getRandomValue(Calendar.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoCalendar s SET s.name=Vivek where s.name=Kuldeep"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCalendar newStudent = em.find(StudentMongoCalendar.class, getRandomValue(Calendar.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Amresh and s.age between " + + getPartialValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Kuldeep and s.age > " + + getPartialValue(short.class) + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertTrue(students.isEmpty()); + + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Kuldeep and s.age >= " + + getPartialValue(short.class) + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + if (student.getId().equals(getMaxValue(Calendar.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.age = " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + Assert.assertEquals(getMaxValue(Calendar.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCalendar s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCalendar student : students) + { + if (student.getId().equals(getMaxValue(Calendar.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoCalendar s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + int count = 0; + for (StudentMongoCalendar student : students) + { + if (student.getId().equals(((Calendar) getMaxValue(Calendar.class)))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + } + Assert.assertEquals(1, count); + em.close(); + } + + public void startCluster() + { + + } + + public void stopCluster() + { + } + + public void createSchema() + { + + } + + public void dropSchema() + { + + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharTest.java new file mode 100644 index 000000000..53ef3eb28 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharTest.java @@ -0,0 +1,575 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoChar; + +public class StudentMongoCharTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoChar.class, getMaxValue(char.class))); + em.remove(em.find(StudentMongoChar.class, getMinValue(char.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of char + StudentMongoChar studentMax = new StudentMongoChar(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(char.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of char + StudentMongoChar studentMin = new StudentMongoChar(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Character) getMinValue(char.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of char + StudentMongoChar student = new StudentMongoChar(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(char.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoChar studentMax = em.find(StudentMongoChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoChar studentMin = em.find(StudentMongoChar.class, getMinValue(char.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoChar student = em.find(StudentMongoChar.class, getRandomValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoChar student = em.find(StudentMongoChar.class, getMaxValue(char.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoChar newStudent = em.find(StudentMongoChar.class, getMaxValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(char.class)); + q.setParameter(2, getMaxValue(char.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getMaxValue(char.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoChar studentMax = em.find(StudentMongoChar.class, getMaxValue(char.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoChar.class, getMaxValue(char.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoChar s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoChar newStudent = em.find(StudentMongoChar.class, getRandomValue(char.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoChar s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoChar newStudent = em.find(StudentMongoChar.class, getRandomValue(char.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoChar s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(char.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoChar s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoChar student : students) + { + if (student.getId() == ((Character) getMaxValue(char.class)).charValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Character) getMinValue(char.class)).charValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(char.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharacterTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharacterTest.java new file mode 100644 index 000000000..098f1c9d0 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoCharacterTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoCharacter; + +public class StudentMongoCharacterTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoCharacter.class, + // getMaxValue(Character.class))); + em.remove(em.find(StudentMongoCharacter.class, getMinValue(Character.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Character + StudentMongoCharacter studentMax = new StudentMongoCharacter(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Character) getMaxValue(Character.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Character + StudentMongoCharacter studentMin = new StudentMongoCharacter(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Character) getMinValue(Character.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Character + StudentMongoCharacter student = new StudentMongoCharacter(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Character) getRandomValue(Character.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoCharacter studentMax = em.find(StudentMongoCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCharacter studentMin = em.find(StudentMongoCharacter.class, getMinValue(Character.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCharacter student = em.find(StudentMongoCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoCharacter student = em.find(StudentMongoCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCharacter newStudent = em.find(StudentMongoCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Character.class)); + q.setParameter(2, getMaxValue(Character.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getMaxValue(Character.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoCharacter studentMax = em.find(StudentMongoCharacter.class, getMaxValue(Character.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoCharacter.class, getMaxValue(Character.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoCharacter s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCharacter newStudent = em.find(StudentMongoCharacter.class, getRandomValue(Character.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoCharacter s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoCharacter newStudent = em.find(StudentMongoCharacter.class, getRandomValue(Character.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoCharacter s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Character.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoCharacter s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoCharacter student : students) + { + if (student.getId().equals(getMaxValue(Character.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Character.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Character.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDateTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDateTest.java new file mode 100644 index 000000000..9ca76aa78 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDateTest.java @@ -0,0 +1,577 @@ +package com.impetus.client.crud.datatypes; + +import java.util.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoDate; + +public class StudentMongoDateTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoDate.class, getMaxValue(Date.class))); + em.remove(em.find(StudentMongoDate.class, getMinValue(Date.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentMongoDate student = new StudentMongoDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentMongoDate studentMax = new StudentMongoDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentMongoDate studentMin = new StudentMongoDate(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDate studentMax = em.find(StudentMongoDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDate studentMin = em.find(StudentMongoDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDate student = em.find(StudentMongoDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoDate student = em.find(StudentMongoDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDate newStudent = em.find(StudentMongoDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Date.class)); + q.setParameter(2, getMaxValue(Date.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDate studentMax = em.find(StudentMongoDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDate newStudent = em.find(StudentMongoDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDate newStudent = em.find(StudentMongoDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoublePrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoublePrimitiveTest.java new file mode 100644 index 000000000..9efa38174 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoublePrimitiveTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoDoublePrimitive; + +public class StudentMongoDoublePrimitiveTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoDoublePrimitive.class, + // getMaxValue(double.class))); + em.remove(em.find(StudentMongoDoublePrimitive.class, getMinValue(double.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentMongoDoublePrimitive studentMax = new StudentMongoDoublePrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentMongoDoublePrimitive studentMin = new StudentMongoDoublePrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentMongoDoublePrimitive student = new StudentMongoDoublePrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDoublePrimitive studentMax = em.find(StudentMongoDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoublePrimitive studentMin = em.find(StudentMongoDoublePrimitive.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoublePrimitive student = em.find(StudentMongoDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoDoublePrimitive student = em.find(StudentMongoDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoublePrimitive newStudent = em.find(StudentMongoDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(double.class)); + q.setParameter(2, getMaxValue(double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDoublePrimitive studentMax = em.find(StudentMongoDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoDoublePrimitive.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoDoublePrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoublePrimitive newStudent = em.find(StudentMongoDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoDoublePrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoublePrimitive newStudent = em.find(StudentMongoDoublePrimitive.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoublePrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoDoublePrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDoublePrimitive student : students) + { + if (student.getId() == ((Double) getMaxValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Double) getMinValue(Double.class)).doubleValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoubleWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoubleWrapperTest.java new file mode 100644 index 000000000..d715f608f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoDoubleWrapperTest.java @@ -0,0 +1,572 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoDoubleWrapper; + +public class StudentMongoDoubleWrapperTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + } + + @After + public void tearDown() throws Exception + { + dropSchema(); + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Double + StudentMongoDoubleWrapper studentMax = new StudentMongoDoubleWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Double) getMaxValue(Double.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Double + StudentMongoDoubleWrapper studentMin = new StudentMongoDoubleWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Double) getMinValue(Double.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Double + StudentMongoDoubleWrapper student = new StudentMongoDoubleWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Double) getRandomValue(Double.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDoubleWrapper studentMax = em.find(StudentMongoDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoubleWrapper studentMin = em.find(StudentMongoDoubleWrapper.class, getMinValue(Double.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoubleWrapper student = em.find(StudentMongoDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoDoubleWrapper student = em.find(StudentMongoDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoubleWrapper newStudent = em.find(StudentMongoDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Double.class)); + q.setParameter(2, getMaxValue(Double.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getMaxValue(Double.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoDoubleWrapper studentMax = em.find(StudentMongoDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoDoubleWrapper.class, getMaxValue(Double.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoDoubleWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoubleWrapper newStudent = em.find(StudentMongoDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoDoubleWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoDoubleWrapper newStudent = em.find(StudentMongoDoubleWrapper.class, getRandomValue(Double.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoDoubleWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Double.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoDoubleWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoDoubleWrapper student : students) + { + if (student.getId().equals(getMaxValue(Double.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Double.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Double.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + EntityManager em = emf.createEntityManager(); + truncateMongo(em, PERSISTENCE_UNIT, "StudentMongoDoubleWrapper"); + + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatPrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatPrimitiveTest.java new file mode 100644 index 000000000..4e7a84d10 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatPrimitiveTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoFloatPrimitive; + +public class StudentMongoFloatPrimitiveTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoFloatPrimitive.class, + // getMaxValue(float.class))); + em.remove(em.find(StudentMongoFloatPrimitive.class, getMinValue(float.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of float + StudentMongoFloatPrimitive studentMax = new StudentMongoFloatPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of float + StudentMongoFloatPrimitive studentMin = new StudentMongoFloatPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Float) getMinValue(float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of float + StudentMongoFloatPrimitive student = new StudentMongoFloatPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoFloatPrimitive studentMax = em.find(StudentMongoFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatPrimitive studentMin = em.find(StudentMongoFloatPrimitive.class, getMinValue(float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatPrimitive student = em.find(StudentMongoFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoFloatPrimitive student = em.find(StudentMongoFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatPrimitive newStudent = em.find(StudentMongoFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(float.class)); + q.setParameter(2, getMaxValue(float.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getMaxValue(float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoFloatPrimitive studentMax = em.find(StudentMongoFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoFloatPrimitive.class, getMaxValue(float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoFloatPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatPrimitive newStudent = em.find(StudentMongoFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoFloatPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatPrimitive newStudent = em.find(StudentMongoFloatPrimitive.class, getRandomValue(float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoFloatPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoFloatPrimitive student : students) + { + if (student.getId() == ((Float) getMaxValue(float.class)).floatValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Float) getMinValue(float.class)).floatValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatWrapperTest.java new file mode 100644 index 000000000..cd6e489ee --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoFloatWrapperTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoFloatWrapper; + +public class StudentMongoFloatWrapperTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoFloatWrapper.class, + // getMaxValue(Float.class))); + em.remove(em.find(StudentMongoFloatWrapper.class, getMinValue(Float.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Float + StudentMongoFloatWrapper studentMax = new StudentMongoFloatWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Float) getMaxValue(Float.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Float + StudentMongoFloatWrapper studentMin = new StudentMongoFloatWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Float) getMinValue(Float.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Float + StudentMongoFloatWrapper student = new StudentMongoFloatWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Float) getRandomValue(Float.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoFloatWrapper studentMax = em.find(StudentMongoFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatWrapper studentMin = em.find(StudentMongoFloatWrapper.class, getMinValue(Float.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatWrapper student = em.find(StudentMongoFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoFloatWrapper student = em.find(StudentMongoFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatWrapper newStudent = em.find(StudentMongoFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Float.class)); + q.setParameter(2, getMaxValue(Float.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getMaxValue(Float.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoFloatWrapper studentMax = em.find(StudentMongoFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoFloatWrapper.class, getMaxValue(Float.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoFloatWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatWrapper newStudent = em.find(StudentMongoFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoFloatWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoFloatWrapper newStudent = em.find(StudentMongoFloatWrapper.class, getRandomValue(Float.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoFloatWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Float.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoFloatWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoFloatWrapper student : students) + { + if (student.getId().equals(getMaxValue(Float.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Float.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Float.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntTest.java new file mode 100644 index 000000000..a4a68ed6b --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntTest.java @@ -0,0 +1,589 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoInt; + +public class StudentMongoIntTest extends MongoBase +{ + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoInt.class, getMaxValue(int.class))); + // em.remove(em.find(StudentMongoInt.class, getMinValue(int.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of int + StudentMongoInt studentMax = new StudentMongoInt(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(int.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of int + StudentMongoInt studentMin = new StudentMongoInt(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Integer) getMinValue(int.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of int + StudentMongoInt student = new StudentMongoInt(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(int.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoInt studentMax = em.find(StudentMongoInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInt studentMin = em.find(StudentMongoInt.class, getMinValue(int.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInt student = em.find(StudentMongoInt.class, getRandomValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoInt student = em.find(StudentMongoInt.class, getMaxValue(int.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInt newStudent = em.find(StudentMongoInt.class, getMaxValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.id between " + getMinValue(int.class) + " and " + + getMaxValue(int.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Integer) getMinValue(int.class)).intValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getMaxValue(int.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoInt studentMax = em.find(StudentMongoInt.class, getMaxValue(int.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoInt.class, getMaxValue(int.class)); + Assert.assertNull(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + + StudentMongoInt studentMin = em.find(StudentMongoInt.class, getMinValue(int.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals("Kuldeep", studentMin.getName()); + em.remove(studentMin); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMin = em.find(StudentMongoInt.class, getMinValue(int.class)); + Assert.assertNull(studentMin); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoInt s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInt newStudent = em.find(StudentMongoInt.class, getRandomValue(int.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoInt s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInt newStudent = em.find(StudentMongoInt.class, getRandomValue(int.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInt s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(int.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoInt s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoInt student : students) + { + if (student.getId() == ((Integer) getMaxValue(int.class)).intValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Integer) getMinValue(int.class)).intValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(int.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntegerTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntegerTest.java new file mode 100644 index 000000000..d967009cd --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoIntegerTest.java @@ -0,0 +1,574 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoInteger; + +public class StudentMongoIntegerTest extends MongoBase +{ + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoInteger.class, + // getMaxValue(Integer.class))); + em.remove(em.find(StudentMongoInteger.class, getMinValue(Integer.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of integer + StudentMongoInteger studentMax = new StudentMongoInteger(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Integer) getMaxValue(Integer.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of integer + StudentMongoInteger studentMin = new StudentMongoInteger(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Integer) getMinValue(Integer.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of integer + StudentMongoInteger student = new StudentMongoInteger(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Integer) getRandomValue(Integer.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoInteger studentMax = em.find(StudentMongoInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInteger studentMin = em.find(StudentMongoInteger.class, getMinValue(Integer.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInteger student = em.find(StudentMongoInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoInteger student = em.find(StudentMongoInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInteger newStudent = em.find(StudentMongoInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Integer.class)); + q.setParameter(2, getMaxValue(Integer.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Integer.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getMaxValue(Integer.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoInteger studentMax = em.find(StudentMongoInteger.class, getMaxValue(Integer.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoInteger.class, getMaxValue(Integer.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoInteger s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInteger newStudent = em.find(StudentMongoInteger.class, getRandomValue(Integer.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoInteger s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoInteger newStudent = em.find(StudentMongoInteger.class, getRandomValue(Integer.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoInteger s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Integer.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoInteger s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoInteger student : students) + { + if (student.getId().equals(getMaxValue(Integer.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Integer.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Integer.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongPrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongPrimitiveTest.java new file mode 100644 index 000000000..db634d075 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongPrimitiveTest.java @@ -0,0 +1,573 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoLongPrimitive; + +public class StudentMongoLongPrimitiveTest extends MongoBase +{ + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class))); + em.remove(em.find(StudentMongoLongPrimitive.class, getMinValue(long.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of long + StudentMongoLongPrimitive studentMax = new StudentMongoLongPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of long + StudentMongoLongPrimitive studentMin = new StudentMongoLongPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Long) getMinValue(long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of long + StudentMongoLongPrimitive student = new StudentMongoLongPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoLongPrimitive studentMax = em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongPrimitive studentMin = em.find(StudentMongoLongPrimitive.class, getMinValue(long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongPrimitive student = em.find(StudentMongoLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoLongPrimitive student = em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongPrimitive newStudent = em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(long.class)); + q.setParameter(2, getMaxValue(long.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Long) getMinValue(long.class)).longValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getMaxValue(long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoLongPrimitive studentMax = em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoLongPrimitive.class, getMaxValue(long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoLongPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongPrimitive newStudent = em.find(StudentMongoLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoLongPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongPrimitive newStudent = em.find(StudentMongoLongPrimitive.class, getRandomValue(long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoLongPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoLongPrimitive student : students) + { + if (student.getId() == ((Long) getMaxValue(long.class)).longValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Long) getMinValue(long.class)).longValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongWrapperTest.java new file mode 100644 index 000000000..20f5ae079 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoLongWrapperTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoLongWrapper; + +public class StudentMongoLongWrapperTest extends MongoBase +{ + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class))); + em.remove(em.find(StudentMongoLongWrapper.class, getMinValue(Long.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Long + StudentMongoLongWrapper studentMax = new StudentMongoLongWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Long) getMaxValue(Long.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Long + StudentMongoLongWrapper studentMin = new StudentMongoLongWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Long) getMinValue(Long.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Long + StudentMongoLongWrapper student = new StudentMongoLongWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Long) getRandomValue(Long.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoLongWrapper studentMax = em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongWrapper studentMin = em.find(StudentMongoLongWrapper.class, getMinValue(Long.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongWrapper student = em.find(StudentMongoLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoLongWrapper student = em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongWrapper newStudent = em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.id between " + getMinValue(Long.class) + " and " + + getMaxValue(Long.class); + // query = + // "Select s From StudentMongoLongWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + // q.setParameter(1, getMinValue(Long.class)); + // q.setParameter(2, getMaxValue(Long.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Long.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getMaxValue(Long.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoLongWrapper studentMax = em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoLongWrapper.class, getMaxValue(Long.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoLongWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongWrapper newStudent = em.find(StudentMongoLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoLongWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoLongWrapper newStudent = em.find(StudentMongoLongWrapper.class, getRandomValue(Long.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoLongWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Long.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoLongWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoLongWrapper student : students) + { + if (student.getId().equals(getMaxValue(Long.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Long.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Long.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortPrimitiveTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortPrimitiveTest.java new file mode 100644 index 000000000..60f571d02 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortPrimitiveTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoShortPrimitive; + +public class StudentMongoShortPrimitiveTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoShortPrimitive.class, + // getMaxValue(short.class))); + em.remove(em.find(StudentMongoShortPrimitive.class, getMinValue(short.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentMongoShortPrimitive studentMax = new StudentMongoShortPrimitive(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentMongoShortPrimitive studentMin = new StudentMongoShortPrimitive(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Short) getMinValue(Short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentMongoShortPrimitive student = new StudentMongoShortPrimitive(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoShortPrimitive studentMax = em.find(StudentMongoShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortPrimitive studentMin = em.find(StudentMongoShortPrimitive.class, getMinValue(Short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortPrimitive student = em.find(StudentMongoShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoShortPrimitive student = em.find(StudentMongoShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortPrimitive newStudent = em.find(StudentMongoShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(short.class)); + q.setParameter(2, getMaxValue(short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Short) getMinValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoShortPrimitive studentMax = em.find(StudentMongoShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoShortPrimitive.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoShortPrimitive s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortPrimitive newStudent = em.find(StudentMongoShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoShortPrimitive s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortPrimitive newStudent = em.find(StudentMongoShortPrimitive.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortPrimitive s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoShortPrimitive s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoShortPrimitive student : students) + { + if (student.getId() == ((Short) getMaxValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId() == ((Short) getMinValue(Short.class)).shortValue()) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortWrapperTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortWrapperTest.java new file mode 100644 index 000000000..69894e843 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoShortWrapperTest.java @@ -0,0 +1,576 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoShortWrapper; + +public class StudentMongoShortWrapperTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoShortWrapper.class, + // getMaxValue(Short.class))); + em.remove(em.find(StudentMongoShortWrapper.class, getMinValue(Short.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of Short + StudentMongoShortWrapper studentMax = new StudentMongoShortWrapper(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Short) getMaxValue(Short.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Short + StudentMongoShortWrapper studentMin = new StudentMongoShortWrapper(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Short) getMinValue(Short.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of Short + StudentMongoShortWrapper student = new StudentMongoShortWrapper(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Short) getRandomValue(Short.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoShortWrapper studentMax = em.find(StudentMongoShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortWrapper studentMin = em.find(StudentMongoShortWrapper.class, getMinValue(Short.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortWrapper student = em.find(StudentMongoShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoShortWrapper student = em.find(StudentMongoShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortWrapper newStudent = em.find(StudentMongoShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Short.class)); + q.setParameter(2, getMaxValue(Short.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Short.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getMaxValue(Short.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoShortWrapper studentMax = em.find(StudentMongoShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoShortWrapper.class, getMaxValue(Short.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoShortWrapper s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortWrapper newStudent = em.find(StudentMongoShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoShortWrapper s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoShortWrapper newStudent = em.find(StudentMongoShortWrapper.class, getRandomValue(Short.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoShortWrapper s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Short.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoShortWrapper s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoShortWrapper student : students) + { + if (student.getId().equals(getMaxValue(Short.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Short.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Short.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoSqlDateTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoSqlDateTest.java new file mode 100644 index 000000000..e1b173bc4 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoSqlDateTest.java @@ -0,0 +1,581 @@ +package com.impetus.client.crud.datatypes; + +import java.sql.Date; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoSqlDate; + +public class StudentMongoSqlDateTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + } + + @After + public void tearDown() throws Exception + { + // EntityManager em = emf.createEntityManager(); + // // em.remove(em.find(StudentMongoSqlDate.class, + // // getMaxValue(Date.class))); + // em.remove(em.find(StudentMongoSqlDate.class, + // getMinValue(Date.class))); + // if (AUTO_MANAGE_SCHEMA) + // { + dropSchema(); + // } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Date + StudentMongoSqlDate student = new StudentMongoSqlDate(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Date) getRandomValue(Date.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Date + StudentMongoSqlDate studentMax = new StudentMongoSqlDate(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Date) getMaxValue(Date.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Date + StudentMongoSqlDate studentMin = new StudentMongoSqlDate(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Date) getMinValue(Date.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoSqlDate studentMax = em.find(StudentMongoSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoSqlDate studentMin = em.find(StudentMongoSqlDate.class, getMinValue(Date.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoSqlDate student = em.find(StudentMongoSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoSqlDate student = em.find(StudentMongoSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoSqlDate newStudent = em.find(StudentMongoSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Date.class)); + q.setParameter(2, getMaxValue(Date.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getMaxValue(Date.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoSqlDate studentMax = em.find(StudentMongoSqlDate.class, getMaxValue(Date.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoSqlDate.class, getMaxValue(Date.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoSqlDate s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoSqlDate newStudent = em.find(StudentMongoSqlDate.class, getRandomValue(Date.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoSqlDate s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoSqlDate newStudent = em.find(StudentMongoSqlDate.class, getRandomValue(Date.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + Assert.assertEquals(getRandomValue(Date.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoSqlDate s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Date.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoSqlDate s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoSqlDate student : students) + { + if (student.getId().equals(getMaxValue(Date.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Date.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Date) getRandomValue(Date.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + EntityManager em = emf.createEntityManager(); + truncateMongo(em, PERSISTENCE_UNIT, "StudentMongoSqlDate"); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoStringTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoStringTest.java new file mode 100644 index 000000000..eb5346044 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoStringTest.java @@ -0,0 +1,567 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoString; + +public class StudentMongoStringTest extends MongoBase +{ + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoString.class, + // getMaxValue(String.class))); + em.remove(em.find(StudentMongoString.class, getMinValue(String.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of String + StudentMongoString studentMax = new StudentMongoString(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((String) getMaxValue(String.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of String + StudentMongoString studentMin = new StudentMongoString(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((String) getMinValue(String.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of String + StudentMongoString student = new StudentMongoString(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((String) getRandomValue(String.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoString studentMax = em.find(StudentMongoString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoString studentMin = em.find(StudentMongoString.class, getMinValue(String.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoString student = em.find(StudentMongoString.class, getRandomValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoString student = em.find(StudentMongoString.class, getMaxValue(String.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoString newStudent = em.find(StudentMongoString.class, getMaxValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.id between " + getMinValue(String.class) + " and " + + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + int count = 0; + for (StudentMongoString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getMaxValue(String.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoString studentMax = em.find(StudentMongoString.class, getMaxValue(String.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoString.class, getMaxValue(String.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoString s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoString newStudent = em.find(StudentMongoString.class, getRandomValue(String.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoString s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoString newStudent = em.find(StudentMongoString.class, getRandomValue(String.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoString student : students) + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoString s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(String.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoString s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoString student : students) + { + if (student.getId().equals(getMaxValue(String.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(String.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(String.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTest.java new file mode 100644 index 000000000..92aafbdf4 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTest.java @@ -0,0 +1,665 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes; + +import java.math.BigInteger; +import java.util.List; + +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +/** + * The Class StudentDaoTest. + * + * @author Vivek Mishra + */ +public class StudentMongoTest extends StudentMongoBase +{ + String persistenceUnit = "mongoTest"; + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + /** + * Sets the up. + * + * @throws Exception + * the exception + */ + @Before + public void setUp() throws Exception + { + setupInternal(persistenceUnit); + } + + /** + * Tear down. + * + * @throws Exception + * the exception + */ + @After + public void tearDown() throws Exception + { + teardownInternal(persistenceUnit); + } + + @SuppressWarnings("deprecation") + @Test + @PerfTest(invocations = 1) + public void executeTests() + { + onInsert(); + onMerge(); + } + + /** + * Test method for. + * + * @throws InstantiationException + * the instantiation exception + * @throws IllegalAccessException + * the illegal access exception + * {@link com.impetus.kundera.examples.student.StudentDao#saveStudent(com.impetus.kundera.examples.crud.datatype.entities.StudentMongo)} + * . + */ + + public void onInsert() + { + try + { + onInsert(new StudentMongo()); + } + catch (InstantiationException e) + { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + catch (IllegalAccessException e) + { + e.printStackTrace(); + Assert.fail(e.getMessage()); + } + + // find by id. + StudentEntityDef s = em.find(StudentMongo.class, studentId1); + assertOnDataTypes((StudentMongo) s); + + // // find by name. + assertFindByName(em, "StudentMongo", StudentMongo.class, "Amresh", "studentName"); + + // find by name and age. + assertFindByNameAndAge(em, "StudentMongo", StudentMongo.class, "Amresh", "10", "studentName"); + + // find by name, age clause + assertFindByNameAndAgeGTAndLT(em, "StudentMongo", StudentMongo.class, "Amresh", "10", "20", "studentName"); + // + // // find by between clause + assertFindByNameAndAgeBetween(em, "StudentMongo", StudentMongo.class, "Amresh", "10", "15", "studentName"); + + // find by Range. + assertFindByRange(em, "StudentMongo", StudentMongo.class, "12345677", "12345678", "studentId"); + + // find by without where clause. + assertFindWithoutWhereClause(em, "StudentMongo", StudentMongo.class); + + // Query on Date. + String query = "Select s from StudentMongo s where s.enrolmentDate =:enrolmentDate"; + Query q = em.createQuery(query); + q.setParameter("enrolmentDate", enrolmentDate); + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + // Query on long. + query = "Select s from StudentMongo s where s.uniqueId =?1"; + q = em.createQuery(query); + q.setParameter(1, 78575785897L); + + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + + // Assert on boolean. + query = "Select s from StudentMongo s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, true); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + } + + } + + // with false. + query = "Select s from StudentMongo s where s.isExceptional =?1"; + q = em.createQuery(query); + q.setParameter(1, false); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + + // query on int. + + query = "Select s from StudentMongo s where s.age =?1"; + q = em.createQuery(query); + q.setParameter(1, 10); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + + // query on char (semester) + + query = "Select s from StudentMongo s where s.semester =?1"; + q = em.createQuery(query); + q.setParameter(1, 'A'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(10, results.get(0).getAge()); + Assert.assertEquals('A', results.get(0).getSemester()); + + // query on float (percentage) + query = "Select s from StudentMongo s where s.percentage =?1"; + q = em.createQuery(query); + q.setParameter(1, 61.6f); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + + // query on double (height) + + query = "Select s from StudentMongo s where s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on cgpa. + query = "Select s from StudentMongo s where s.cgpa =?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + } + + } + + // query on yearsSpent. + Integer i = new Integer(3); + query = "Select s from StudentMongo s where s.yearsSpent = 3"; + q = em.createQuery(query); + // q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + + } + + // query on yearsSpent. + query = "Select s from StudentMongo s where s.yearsSpent =?1"; + q = em.createQuery(query); + q.setParameter(1, new Integer(3)); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + } + + } + + // query on digitalSignature. + query = "Select s from StudentMongo s where s.digitalSignature =?1"; + q = em.createQuery(query); + q.setParameter(1, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(2, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(0).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(0).getDigitalSignature()); + } + } + + // query on cpga and digitalSignature. + query = "Select s from StudentMongo s where s.cgpa =?1 and s.digitalSignature >= ?2 and s.digitalSignature <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + } + + // query on cpga and digitalSignature parameter appended with String + // . + query = "Select s from StudentMongo s where s.cgpa = 8 and s.digitalSignature >= 5 and s.digitalSignature <= 50"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + } + + // query on cpga and digitalSignature. + query = "Select s from StudentMongo s where s.digitalSignature >= ?2 and s.digitalSignature <= ?3 and s.cgpa =?1"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, (byte) 5); + q.setParameter(3, (byte) 50); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + } + + // query on percentage and height. + query = "Select s from StudentMongo s where s.percentage >= ?2 and s.percentage <= ?3 and s.height =?1"; + q = em.createQuery(query); + q.setParameter(1, 163.76765654); + q.setParameter(2, 61.6f); + q.setParameter(3, 69.6f); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on percentage and height parameter appended in string. + query = "Select s from StudentMongo s where s.percentage >= 61.6 and s.percentage <= 69.6 and s.height = 163.76765654"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(61.6f, results.get(0).getPercentage()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // query on cpga and uniqueId. + query = "Select s from StudentMongo s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + } + + for (StudentMongo student : results) + { + Assert.assertTrue(student.getUniqueId() == 78575785897L || student.getUniqueId() == 78575785898L + || student.getUniqueId() == 78575785899L); + } + + // query on cpga and semester. + query = "Select s from StudentMongo s where s.cgpa =?1 and s.semester >= ?2 and s.semester < ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 8); + q.setParameter(2, 'A'); + q.setParameter(3, 'C'); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals((short) 8, results.get(0).getCgpa()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + Assert.assertEquals(78575785897L, results.get(0).getUniqueId()); + Assert.assertEquals(10, results.get(0).getAge()); + + // query on cpga and semester with appending in string. + query = "Select s from StudentMongo s where s.cgpa = 8 and s.semester >= A and s.semester <= C"; + q = em.createQuery(query); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(3, results.size()); + for (StudentMongo studentMongo : results) + { + if (studentMongo.getStudentId() == (Long) studentId1) + { + Assert.assertEquals(10, studentMongo.getAge()); + Assert.assertEquals(false, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 5, results.get(0).getDigitalSignature()); + } + else if (studentMongo.getStudentId() == (Long) studentId2) + { + Assert.assertEquals(20, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + else + { + Assert.assertEquals(15, studentMongo.getAge()); + Assert.assertEquals(true, studentMongo.isExceptional()); + Assert.assertEquals(8, studentMongo.getCgpa()); + Assert.assertEquals(i, studentMongo.getYearsSpent()); + Assert.assertEquals((byte) 50, results.get(1).getDigitalSignature()); + } + } + + for (StudentMongo student : results) + { + Assert.assertTrue(student.getUniqueId() == 78575785897L || student.getUniqueId() == 78575785898L + || student.getUniqueId() == 78575785899L); + } + for (StudentMongo student : results) + { + Assert.assertTrue(student.getAge() == 15 || student.getAge() == 20 || student.getAge() == 10); + } + + // query on invalid cpga and uniqueId. + query = "Select s from StudentMongo s where s.cgpa =?1 and s.uniqueId >= ?2 and s.uniqueId <= ?3"; + q = em.createQuery(query); + q.setParameter(1, (short) 2); + q.setParameter(2, 78575785897L); + q.setParameter(3, 78575785899L); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + // query on big integer. + query = "Select s from StudentMongo s where s.bigInteger =?1"; + q = em.createQuery(query); + q.setParameter(1, bigInteger); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + Assert.assertEquals(false, results.get(0).isExceptional()); + Assert.assertEquals(163.76765654, results.get(0).getHeight()); + + // invalid. + q.setParameter(1, new BigInteger("1234567823")); + results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertTrue(results.isEmpty()); + + } + + /** + * On merge. + */ + public void onMerge() + { + em.persist(prepareData((Long) studentId1, 78575785897L, "Amresh", true, 10, 'C', (byte) 5, (short) 8, + (float) 69.6, 163.76765654, enrolmentDate, enrolmentTime, joiningDateAndTime, new Integer(3), new Long( + 978423946455l), 135434.89, newSqlDate, sqlTime, sqlTimestamp, bigDecimal, bigInteger, calendar, + new StudentMongo())); + StudentMongo s = em.find(StudentMongo.class, studentId1); + Assert.assertNotNull(s); + Assert.assertEquals("Amresh", s.getStudentName()); + // modify record. + s.setStudentName("NewAmresh"); + em.merge(s); + // emf.close(); + Query q = em.createQuery("Select p from StudentMongo p where p.studentName = NewAmresh"); + try + { + List results = q.getResultList(); + Assert.assertNotNull(results); + Assert.assertEquals(1, results.size()); + } + catch (Exception e) + { + Assert.fail("Failure onMerge test"); + } + } + + @Override + void startServer() + { + } + + @Override + void stopServer() + { + } + + @Override + void createSchema() + { + } + + @Override + void deleteSchema() + { + em.remove(em.find(StudentMongo.class, studentId1)); + em.remove(em.find(StudentMongo.class, studentId2)); + em.remove(em.find(StudentMongo.class, studentId3)); + } + +} \ No newline at end of file diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimeTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimeTest.java new file mode 100644 index 000000000..0bde24dc1 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimeTest.java @@ -0,0 +1,578 @@ +package com.impetus.client.crud.datatypes; + +import java.sql.Time; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoTime; + +public class StudentMongoTimeTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoTime.class, getMaxValue(Time.class))); + em.remove(em.find(StudentMongoTime.class, getMinValue(Time.class))); + emf.close(); + if (AUTO_MANAGE_SCHEMA) + { + dropSchema(); + } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentMongoTime student = new StudentMongoTime(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Time) getRandomValue(Time.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentMongoTime studentMax = new StudentMongoTime(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Time) getMaxValue(Time.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Time + StudentMongoTime studentMin = new StudentMongoTime(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Time) getMinValue(Time.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoTime studentMax = em.find(StudentMongoTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTime studentMin = em.find(StudentMongoTime.class, getMinValue(Time.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTime student = em.find(StudentMongoTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoTime student = em.find(StudentMongoTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTime newStudent = em.find(StudentMongoTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Time.class)); + q.setParameter(2, getMaxValue(Time.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getMaxValue(Time.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoTime studentMax = em.find(StudentMongoTime.class, getMaxValue(Time.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoTime.class, getMaxValue(Time.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoTime s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTime newStudent = em.find(StudentMongoTime.class, getRandomValue(Time.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentMongoTime s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTime newStudent = em.find(StudentMongoTime.class, getRandomValue(Time.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + Assert.assertEquals(getRandomValue(Time.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTime s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Time.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoTime s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoTime student : students) + { + if (student.getId().equals(getMaxValue(Time.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Time.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Time) getRandomValue(Time.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimestampTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimestampTest.java new file mode 100644 index 000000000..ccbd3e32f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoTimestampTest.java @@ -0,0 +1,582 @@ +package com.impetus.client.crud.datatypes; + +import java.sql.Timestamp; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoTimestamp; + +public class StudentMongoTimestampTest extends MongoBase +{ + + private static final String keyspace = "KunderaMongoDataType"; + + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + if (RUN_IN_EMBEDDED_MODE) + { + startCluster(); + } + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); + } + + @After + public void tearDown() throws Exception + { + // EntityManager em = emf.createEntityManager(); + // em.remove(em.find(StudentMongoTimestamp.class, + // getMaxValue(Timestamp.class))); + // em.remove(em.find(StudentMongoTimestamp.class, + // getMinValue(Timestamp.class))); + // if (AUTO_MANAGE_SCHEMA) + // { + dropSchema(); + // } + if (RUN_IN_EMBEDDED_MODE) + { + stopCluster(); + } + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert random value of Time + StudentMongoTimestamp student = new StudentMongoTimestamp(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((Timestamp) getRandomValue(Timestamp.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + + // Insert max value of Time + StudentMongoTimestamp studentMax = new StudentMongoTimestamp(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((Timestamp) getMaxValue(Timestamp.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of Timestamp + StudentMongoTimestamp studentMin = new StudentMongoTimestamp(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((Timestamp) getMinValue(Timestamp.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoTimestamp studentMax = em.find(StudentMongoTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTimestamp studentMin = em.find(StudentMongoTimestamp.class, getMinValue(Timestamp.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTimestamp student = em.find(StudentMongoTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoTimestamp student = em.find(StudentMongoTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTimestamp newStudent = em.find(StudentMongoTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(Timestamp.class)); + q.setParameter(2, getMaxValue(Timestamp.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getMaxValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoTimestamp studentMax = em.find(StudentMongoTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoTimestamp.class, getMaxValue(Timestamp.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoTimestamp s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTimestamp newStudent = em.find(StudentMongoTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String upTimeQuery = "Update StudentMongoTimestamp s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(upTimeQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoTimestamp newStudent = em.find(StudentMongoTimestamp.class, getRandomValue(Timestamp.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Amresh and s.age between " + + getMinValue(short.class) + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + Assert.assertEquals(getRandomValue(Timestamp.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoTimestamp s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(Timestamp.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoTimestamp s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoTimestamp student : students) + { + if (student.getId().equals(getMaxValue(Timestamp.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(Timestamp.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(((Timestamp) getRandomValue(Timestamp.class)).getTime(), student.getId().getTime()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + EntityManager em = emf.createEntityManager(); + truncateMongo(em, PERSISTENCE_UNIT, "StudentMongoTimestamp"); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoUUIDTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoUUIDTest.java new file mode 100644 index 000000000..2cc296195 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/StudentMongoUUIDTest.java @@ -0,0 +1,558 @@ +package com.impetus.client.crud.datatypes; + +import java.util.List; +import java.util.UUID; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.datatypes.entities.StudentMongoUUID; +import com.impetus.client.utils.MongoUtils; + +public class StudentMongoUUIDTest extends MongoBase +{ + private EntityManagerFactory emf; + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("MongoDataTypeTest"); + } + + @After + public void tearDown() throws Exception + { + EntityManager em = emf.createEntityManager(); + em.remove(em.find(StudentMongoUUID.class, getMinValue(UUID.class))); + MongoUtils.dropDatabase(emf, "MongoDataTypeTest"); + emf.close(); + } + + @Test + public void testExecuteUseSameEm() + { + testPersist(true); + testFindById(true); + testMerge(true); + testFindByQuery(true); + testNamedQueryUseSameEm(true); + testDelete(true); + } + + @Test + public void testExecute() + { + testPersist(false); + testFindById(false); + testMerge(false); + testFindByQuery(false); + testNamedQuery(false); + testDelete(false); + } + + public void testPersist(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + // Insert max value of UUID + StudentMongoUUID studentMax = new StudentMongoUUID(); + studentMax.setAge((Short) getMaxValue(short.class)); + studentMax.setId((UUID) getMaxValue(UUID.class)); + studentMax.setName((String) getMaxValue(String.class)); + em.persist(studentMax); + + // Insert min value of UUID + StudentMongoUUID studentMin = new StudentMongoUUID(); + studentMin.setAge((Short) getMinValue(short.class)); + studentMin.setId((UUID) getMinValue(UUID.class)); + studentMin.setName((String) getMinValue(String.class)); + em.persist(studentMin); + + // Insert random value of UUID + StudentMongoUUID student = new StudentMongoUUID(); + student.setAge((Short) getRandomValue(short.class)); + student.setId((UUID) getRandomValue(UUID.class)); + student.setName((String) getRandomValue(String.class)); + em.persist(student); + em.close(); + } + + public void testFindById(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoUUID studentMax = em.find(StudentMongoUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals(getMaxValue(String.class), studentMax.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoUUID studentMin = em.find(StudentMongoUUID.class, getMinValue(UUID.class)); + Assert.assertNotNull(studentMin); + Assert.assertEquals(getMinValue(short.class), studentMin.getAge()); + Assert.assertEquals(getMinValue(String.class), studentMin.getName()); + + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoUUID student = em.find(StudentMongoUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + em.close(); + } + + public void testMerge(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + StudentMongoUUID student = em.find(StudentMongoUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(student); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals(getMaxValue(String.class), student.getName()); + + student.setName("Kuldeep"); + em.merge(student); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoUUID newStudent = em.find(StudentMongoUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getMaxValue(short.class), newStudent.getAge()); + Assert.assertEquals("Kuldeep", newStudent.getName()); + } + + public void testFindByQuery(boolean useSameEm) + { + findAllQuery(); + findByName(); + findByAge(); + findByNameAndAgeGTAndLT(); + findByNameAndAgeGTEQAndLTEQ(); + findByNameAndAgeGTAndLTEQ(); + findByNameAndAgeWithOrClause(); + findByAgeAndNameGTAndLT(); + findByNameAndAGEBetween(); + // findByRange(); + } + + private void findByAgeAndNameGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.age = " + getMinValue(short.class) + + " and s.name > Amresh and s.name <= " + getMaxValue(String.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByRange() + { + EntityManager em; + String query; + Query q; + List students; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.id between ?1 and ?2"; + q = em.createQuery(query); + q.setParameter(1, getMinValue(UUID.class)); + q.setParameter(2, getMaxValue(UUID.class)); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + private void findByNameAndAgeWithOrClause() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Kuldeep and s.age > " + getMinValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLTEQ() + { + + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Kuldeep and s.age > " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getMaxValue(UUID.class), student.getId()); + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + public void testNamedQueryUseSameEm(boolean useSameEm) + { + updateNamed(true); + deleteNamed(true); + } + + public void testNamedQuery(boolean useSameEm) + { + updateNamed(false); + deleteNamed(false); + } + + public void testDelete(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + + StudentMongoUUID studentMax = em.find(StudentMongoUUID.class, getMaxValue(UUID.class)); + Assert.assertNotNull(studentMax); + Assert.assertEquals(getMaxValue(short.class), studentMax.getAge()); + Assert.assertEquals("Kuldeep", studentMax.getName()); + em.remove(studentMax); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + studentMax = em.find(StudentMongoUUID.class, getMaxValue(UUID.class)); + Assert.assertNull(studentMax); + em.close(); + } + + /** + * + */ + private void deleteNamed(boolean useSameEm) + { + + String deleteQuery = "Delete From StudentMongoUUID s where s.name=Vivek"; + EntityManager em = emf.createEntityManager(); + Query q = em.createQuery(deleteQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoUUID newStudent = em.find(StudentMongoUUID.class, getRandomValue(UUID.class)); + Assert.assertNull(newStudent); + em.close(); + } + + /** + * @return + */ + private void updateNamed(boolean useSameEm) + { + EntityManager em = emf.createEntityManager(); + String updateQuery = "Update StudentMongoUUID s SET s.name=Vivek where s.name=Amresh"; + Query q = em.createQuery(updateQuery); + q.executeUpdate(); + if (!useSameEm) + { + em.close(); + em = emf.createEntityManager(); + } + StudentMongoUUID newStudent = em.find(StudentMongoUUID.class, getRandomValue(UUID.class)); + Assert.assertNotNull(newStudent); + Assert.assertEquals(getRandomValue(short.class), newStudent.getAge()); + Assert.assertEquals("Vivek", newStudent.getName()); + em.close(); + } + + private void findByNameAndAGEBetween() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Amresh and s.age between " + getMinValue(short.class) + + " and " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + } + + private void findByNameAndAgeGTAndLT() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Amresh and s.age > " + getMinValue(short.class) + + " and s.age < " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + + } + Assert.assertEquals(1, count); + em.close(); + + } + + private void findByNameAndAgeGTEQAndLTEQ() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Kuldeep and s.age >= " + getMinValue(short.class) + + " and s.age <= " + getMaxValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + + } + Assert.assertEquals(2, count); + em.close(); + + } + + private void findByAge() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.age = " + getRandomValue(short.class); + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(1, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + Assert.assertEquals(1, count); + em.close(); + } + + /** + * + */ + private void findByName() + { + EntityManager em; + String query; + Query q; + List students; + int count; + em = emf.createEntityManager(); + query = "Select s From StudentMongoUUID s where s.name = Kuldeep"; + q = em.createQuery(query); + students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(2, students.size()); + count = 0; + for (StudentMongoUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else + { + Assert.assertEquals(getMinValue(UUID.class), student.getId()); + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(2, count); + em.close(); + } + + /** + * + */ + private void findAllQuery() + { + EntityManager em = emf.createEntityManager(); + // Selet all query. + String query = "Select s From StudentMongoUUID s "; + Query q = em.createQuery(query); + List students = q.getResultList(); + Assert.assertNotNull(students); + Assert.assertEquals(3, students.size()); + int count = 0; + for (StudentMongoUUID student : students) + { + if (student.getId().equals(getMaxValue(UUID.class))) + { + Assert.assertEquals(getMaxValue(short.class), student.getAge()); + Assert.assertEquals("Kuldeep", student.getName()); + count++; + } + else if (student.getId().equals(getMinValue(UUID.class))) + { + Assert.assertEquals(getMinValue(short.class), student.getAge()); + Assert.assertEquals(getMinValue(String.class), student.getName()); + count++; + } + else + { + Assert.assertEquals(getRandomValue(UUID.class), student.getId()); + Assert.assertEquals(getRandomValue(short.class), student.getAge()); + Assert.assertEquals(getRandomValue(String.class), student.getName()); + count++; + } + } + Assert.assertEquals(3, count); + em.close(); + } + + public void startCluster() + { + } + + public void stopCluster() + { + // TODO Auto-generated method stub + + } + + public void createSchema() + { + } + + public void dropSchema() + { + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Collecte.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Collecte.java new file mode 100644 index 000000000..ee6162a84 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Collecte.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes.entities; + +import java.util.Date; +import java.util.List; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +@Entity +@Table(name = "COLLECTE", schema = "KunderaExamples@mongoTest") +public class Collecte +{ + + @Id + @Column(name = "COLLECTE_ID") + private String id; + + @Column(name = "EAN", nullable = false) + private String EAN; + + @Column(name = "PRODUIT_ID") + private Long idProduit; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name = "dateStatut") + private Date dateStatut; + + @Column(name = "statut") + private int statut; + + // Element collection, will persist co-located + @ElementCollection(fetch = FetchType.LAZY) + @CollectionTable(name = "PHOTOS") + private List photos; + + public String getId() + { + return id; + } + + public void setId(String id) + { + this.id = id; + } + + public String getEAN() + { + return EAN; + } + + public void setEAN(String eAN) + { + EAN = eAN; + } + + public Long getIdProduit() + { + return idProduit; + } + + public void setIdProduit(Long idProduit) + { + this.idProduit = idProduit; + } + + public Date getDateStatut() + { + return dateStatut; + } + + public void setDateStatut(Date dateStatut) + { + this.dateStatut = dateStatut; + } + + public int getStatut() + { + return statut; + } + + public void setStatut(int statut) + { + this.statut = statut; + } + + public List getPhotos() + { + return photos; + } + + public void setPhotos(List photos) + { + this.photos = photos; + } + +} \ No newline at end of file diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Photoo.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Photoo.java new file mode 100644 index 000000000..eb029eeaf --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/Photoo.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +@Embeddable +public class Photoo +{ + + @Column(name = "NOM_PHOTO") + private String nomPhoto; + + @Column(name = "MD5") + private String md5; + + @Column(name = "NOM_FICHIER") + private String nomFichier; + + public String getNomPhoto() + { + return nomPhoto; + } + + public void setNomPhoto(String nomPhoto) + { + this.nomPhoto = nomPhoto; + } + + public String getMd5() + { + return md5; + } + + public void setMd5(String md5) + { + this.md5 = md5; + } + + public String getNomFichier() + { + return nomFichier; + } + + public void setNomFichier(String nomFichier) + { + this.nomFichier = nomFichier; + } + +} \ No newline at end of file diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigDecimal.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigDecimal.java new file mode 100644 index 000000000..9fb23dc03 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigDecimal.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.math.BigDecimal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoBigDecimal", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoBigDecimal +{ + + @Id + private BigDecimal id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigDecimal getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigDecimal id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigInteger.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigInteger.java new file mode 100644 index 000000000..137e98b81 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBigInteger.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.math.BigInteger; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoBigInteger", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoBigInteger +{ + + @Id + private BigInteger id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public BigInteger getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(BigInteger id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanPrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanPrimitive.java new file mode 100644 index 000000000..206fede0d --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanPrimitive.java @@ -0,0 +1,72 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoBooleanPrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoBooleanPrimitive +{ + @Id + private boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanWrapper.java new file mode 100644 index 000000000..0e50288cd --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBooleanWrapper.java @@ -0,0 +1,72 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoBooleanWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoBooleanWrapper +{ + @Id + private Boolean id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Boolean getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Boolean id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBytePrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBytePrimitive.java new file mode 100644 index 000000000..da7198072 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoBytePrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoBytePrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoBytePrimitive +{ + + @Id + private byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoByteWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoByteWrapper.java new file mode 100644 index 000000000..fc1b3a8bb --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoByteWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoByteWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoByteWrapper +{ + + @Id + private Byte id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Byte getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Byte id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCalendar.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCalendar.java new file mode 100644 index 000000000..6b07ba407 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCalendar.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.Calendar; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoCalendar", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoCalendar +{ + + @Id + private Calendar id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Calendar getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Calendar id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoChar.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoChar.java new file mode 100644 index 000000000..8cb8e35a9 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoChar.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoChar", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoChar +{ + + @Id + private char id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public char getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(char id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCharacter.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCharacter.java new file mode 100644 index 000000000..8aaf2aa7e --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoCharacter.java @@ -0,0 +1,72 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoCharacter", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoCharacter +{ + @Id + private Character id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Character getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Character id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDate.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDate.java new file mode 100644 index 000000000..c4c13c567 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDate.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoDate", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoublePrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoublePrimitive.java new file mode 100644 index 000000000..811e9f74f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoublePrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoDoublePrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoDoublePrimitive +{ + + @Id + private double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoubleWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoubleWrapper.java new file mode 100644 index 000000000..09ec4cc95 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoDoubleWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoDoubleWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoDoubleWrapper +{ + + @Id + private Double id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Double getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Double id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatPrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatPrimitive.java new file mode 100644 index 000000000..074877650 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatPrimitive.java @@ -0,0 +1,72 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoFloatPrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoFloatPrimitive +{ + @Id + private float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatWrapper.java new file mode 100644 index 000000000..b27b151d2 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoFloatWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoFloatWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoFloatWrapper +{ + + @Id + private Float id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Float getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Float id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInt.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInt.java new file mode 100644 index 000000000..0bec10750 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInt.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoInt", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoInt +{ + + @Id + private int id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInteger.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInteger.java new file mode 100644 index 000000000..4e171c512 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoInteger.java @@ -0,0 +1,72 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoInteger", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoInteger +{ + @Id + private Integer id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Integer getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Integer id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongPrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongPrimitive.java new file mode 100644 index 000000000..422540a77 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongPrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoLongPrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoLongPrimitive +{ + + @Id + private long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongWrapper.java new file mode 100644 index 000000000..fb5caa475 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoLongWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoLongWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoLongWrapper +{ + + @Id + private Long id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Long getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Long id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortPrimitive.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortPrimitive.java new file mode 100644 index 000000000..4ff75ff2a --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortPrimitive.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoShortPrimitive", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoShortPrimitive +{ + + @Id + private short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortWrapper.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortWrapper.java new file mode 100644 index 000000000..ff30e4670 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoShortWrapper.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoShortWrapper", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoShortWrapper +{ + + @Id + private Short id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Short getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Short id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoSqlDate.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoSqlDate.java new file mode 100644 index 000000000..b97a61155 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoSqlDate.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoSqlDate", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoSqlDate +{ + + @Id + private Date id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Date getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Date id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoString.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoString.java new file mode 100644 index 000000000..19cc38ce3 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoString.java @@ -0,0 +1,73 @@ +package com.impetus.client.crud.datatypes.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoString", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoString +{ + + @Id + private String id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTime.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTime.java new file mode 100644 index 000000000..14a3d8356 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTime.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Time; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoTime", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoTime +{ + + @Id + private Time id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Time getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Time id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTimestamp.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTimestamp.java new file mode 100644 index 000000000..64a449d7a --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoTimestamp.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.sql.Timestamp; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoTimestamp", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoTimestamp +{ + + @Id + private Timestamp id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public Timestamp getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(Timestamp id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoUUID.java b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoUUID.java new file mode 100644 index 000000000..dafd5c6a1 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/crud/datatypes/entities/StudentMongoUUID.java @@ -0,0 +1,75 @@ +package com.impetus.client.crud.datatypes.entities; + +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "StudentMongoUUID", schema = "KunderaMongoDataType@MongoDataTypeTest") +public class StudentMongoUUID +{ + + @Id + private UUID id; + + @Column(name = "AGE") + private short age; + + @Column(name = "NAME") + private String name; + + /** + * @return the id + */ + public UUID getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(UUID id) + { + this.id = id; + } + + /** + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/MongoGeneratedIdTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/MongoGeneratedIdTest.java new file mode 100644 index 000000000..ab2a7906f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/MongoGeneratedIdTest.java @@ -0,0 +1,213 @@ +package com.impetus.client.generatedId; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.GenerationType; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.bson.types.ObjectId; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.impetus.client.generatedId.entites.MongoGeneratedIdDefault; +import com.impetus.client.generatedId.entites.MongoGeneratedIdStrategyAuto; +import com.impetus.client.generatedId.entites.MongoGeneratedIdStrategyIdentity; +import com.impetus.client.generatedId.entites.MongoGeneratedIdStrategySequence; +import com.impetus.client.generatedId.entites.MongoGeneratedIdStrategyTable; +import com.impetus.client.generatedId.entites.MongoGeneratedIdWithOutSequenceGenerator; +import com.impetus.client.generatedId.entites.MongoGeneratedIdWithOutTableGenerator; +import com.impetus.client.generatedId.entites.MongoGeneratedIdWithSequenceGenerator; +import com.impetus.client.generatedId.entites.MongoGeneratedIdWithTableGenerator; +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.utils.MongoUtils; +import com.impetus.kundera.KunderaException; + +public class MongoGeneratedIdTest +{ + + private EntityManagerFactory emf; + + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + } + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory("mongoTest"); + } + + @After + public void tearDown() throws Exception + { + MongoUtils.dropDatabase(emf, "mongoTest"); + emf.close(); + } + + @Test + public void testPersist() + { + EntityManager em = emf.createEntityManager(); + + MongoGeneratedIdDefault idDefault = new MongoGeneratedIdDefault(); + idDefault.setName("kuldeep"); + try + { + em.persist(idDefault); + List list = em.createQuery("Select c from MongoGeneratedIdDefault c") + .getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertEquals("kuldeep", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + idDefault = em.find(MongoGeneratedIdDefault.class, id); + Assert.assertNotNull(idDefault); + Assert.assertEquals("kuldeep", idDefault.getName()); + } + catch (KunderaException e) + { + e.printStackTrace(); + Assert.fail(); + } + MongoGeneratedIdStrategyAuto strategyAuto = new MongoGeneratedIdStrategyAuto(); + strategyAuto.setName("kuldeep"); + try + { + em.persist(strategyAuto); + em.clear(); + List list = em.createQuery("Select c from MongoGeneratedIdStrategyAuto c") + .getResultList(); + Assert.assertNotNull(list); + Assert.assertEquals(1, list.size()); + Assert.assertTrue(list.get(0).getId() instanceof ObjectId); + Assert.assertEquals("kuldeep", list.get(0).getName()); + Object id = list.get(0).getId(); + em.clear(); + strategyAuto = em.find(MongoGeneratedIdStrategyAuto.class, id); + Assert.assertNotNull(strategyAuto); + Assert.assertEquals("kuldeep", strategyAuto.getName()); + } + catch (KunderaException e) + { + Assert.fail(); + } + + MongoGeneratedIdStrategyIdentity strategyIdentity = new MongoGeneratedIdStrategyIdentity(); + strategyIdentity.setName("kuldeep"); + try + { + em.persist(strategyIdentity); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.UnsupportedOperationException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.IDENTITY + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + + MongoGeneratedIdStrategySequence strategySequence = new MongoGeneratedIdStrategySequence(); + strategySequence.setName("Kuldeep"); + try + { + em.persist(strategySequence); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + + MongoGeneratedIdStrategyTable strategyTable = new MongoGeneratedIdStrategyTable(); + strategyTable.setName("KK"); + try + { + em.persist(strategyTable); + Assert.fail(); + + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.TABLE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + + MongoGeneratedIdWithOutSequenceGenerator withOutSequenceGenerator = new MongoGeneratedIdWithOutSequenceGenerator(); + withOutSequenceGenerator.setName("Kuldeep Kumar"); + try + { + em.persist(withOutSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + + MongoGeneratedIdWithOutTableGenerator withOutTableGenerator = new MongoGeneratedIdWithOutTableGenerator(); + withOutTableGenerator.setName("Kuldeep Mishra"); + try + { + em.persist(withOutTableGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.TABLE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + MongoGeneratedIdWithSequenceGenerator withSequenceGenerator = new MongoGeneratedIdWithSequenceGenerator(); + withSequenceGenerator.setName("Kuldeep Kumar Mishra"); + try + { + em.persist(withSequenceGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.SEQUENCE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + MongoGeneratedIdWithTableGenerator withTableGenerator = new MongoGeneratedIdWithTableGenerator(); + withTableGenerator.setName("Kumar Mishra"); + try + { + em.persist(withTableGenerator); + Assert.fail(); + } + catch (KunderaException e) + { + Assert.assertEquals( + "java.lang.IllegalArgumentException: " + GenerationType.class.getSimpleName() + "." + + GenerationType.TABLE + " Strategy not supported by this client :" + + MongoDBClient.class.getName(), e.getMessage()); + } + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdDefault.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdDefault.java new file mode 100644 index 000000000..394ee7637 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdDefault.java @@ -0,0 +1,53 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdDefault", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdDefault +{ + @Id + @GeneratedValue + private String id; + + @Column + private String name; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyAuto.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyAuto.java new file mode 100644 index 000000000..41643d659 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyAuto.java @@ -0,0 +1,59 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.bson.types.ObjectId; + +@Entity +@Table(name = "MongoGeneratedIdStrategyAuto", schema = "KunderaExamples@mongoTest") +@TableGenerator(name = "id_gen") +public class MongoGeneratedIdStrategyAuto +{ + @Id + @GeneratedValue(generator = "id_gen", strategy = GenerationType.AUTO) + private ObjectId id; + + @Column + private String name; + + /** + * @return the id + */ + public ObjectId getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(ObjectId id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyIdentity.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyIdentity.java new file mode 100644 index 000000000..0ab3bdb1c --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyIdentity.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdStrategyIdentity", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdStrategyIdentity +{ + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private String id; + + @Column + private String name; + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategySequence.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategySequence.java new file mode 100644 index 000000000..52f23d1fb --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategySequence.java @@ -0,0 +1,57 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdStrategySequence", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdStrategySequence +{ + @Id + @SequenceGenerator(name = "seq_gen") + @GeneratedValue(generator = "seq_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyTable.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyTable.java new file mode 100644 index 000000000..d73305bb3 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdStrategyTable.java @@ -0,0 +1,59 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "MongoGeneratedIdStrategyTable", schema = "KunderaExamples@mongoTest") +@TableGenerator(name = "table_gen") +public class MongoGeneratedIdStrategyTable +{ + + @Id + @TableGenerator(name = "table_gen_1") + @GeneratedValue(generator = "table_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutSequenceGenerator.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutSequenceGenerator.java new file mode 100644 index 000000000..1aa812b3f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdWithOutSequenceGenerator", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdWithOutSequenceGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutTableGenerator.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutTableGenerator.java new file mode 100644 index 000000000..04d70e0e8 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithOutTableGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdWithOutTableGenerator", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdWithOutTableGenerator +{ + + @Id + @GeneratedValue(strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithSequenceGenerator.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithSequenceGenerator.java new file mode 100644 index 000000000..9190e6682 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithSequenceGenerator.java @@ -0,0 +1,56 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.SequenceGenerator; +import javax.persistence.Table; + +@Entity +@Table(name = "MongoGeneratedIdWithSequenceGenerator", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdWithSequenceGenerator +{ + @Id + @SequenceGenerator(name = "id_gen", allocationSize = 20, initialValue = 80, schema = "KunderaExamples", sequenceName = "newSequence") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.SEQUENCE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} \ No newline at end of file diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithTableGenerator.java b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithTableGenerator.java new file mode 100644 index 000000000..033cac28c --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/generatedId/entites/MongoGeneratedIdWithTableGenerator.java @@ -0,0 +1,57 @@ +package com.impetus.client.generatedId.entites; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +@Entity +@Table(name = "MongoGeneratedIdWithTableGenerator", schema = "KunderaExamples@mongoTest") +public class MongoGeneratedIdWithTableGenerator +{ + + @Id + @TableGenerator(name = "id_gen", allocationSize = 30, initialValue = 100, schema = "KunderaExamples", table = "kundera", pkColumnName = "sequence", valueColumnName = "sequenceValue", pkColumnValue = "kk") + @GeneratedValue(generator = "id_gen", strategy = GenerationType.TABLE) + private int id; + + @Column + private String name; + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/gis/MongoGISTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/gis/MongoGISTest.java new file mode 100644 index 000000000..1be6054fc --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/gis/MongoGISTest.java @@ -0,0 +1,399 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.gis; + +import java.util.List; + +import junit.framework.Assert; + +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; + +import com.impetus.kundera.gis.SurfaceType; +import com.impetus.kundera.gis.geometry.Coordinate; +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.gis.geometry.Polygon; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.vividsolutions.jts.geom.CoordinateSequence; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LinearRing; + +/** + * Test case for GIS + * + * @author amresh.singh + */ +@PerfTest(invocations = 10) +public class MongoGISTest +{ + String persistenceUnit = "mongoTest"; + + PersonGISDao dao; + + static Object testParameter; + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + /** + * @return the testParameter + */ + public Object getTestParameter() + { + return testParameter; + } + + /** + * @param testParameter + * the testParameter to set + */ + public static void setTestParameter(Object testParam) + { + testParameter = testParam; + } + + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + dao = new PersonGISDao(persistenceUnit); + } + + @Test + public synchronized void executeTests() throws Exception + { + addPersons(); + findPerson(); + + // Within Queries + findWithinCircle(); + findWithinTriangle(); + findWithinPolygon(); + findWithinRectangle(); + + // Near Queries + findNear(); + findNearSphere(); + findCentreSphere(); + + findUsingExactCurrentLocation(); + findWithinCircleAndName(); + + // Update/Delete Queries + updateNameWithinCircle(); + deleteNameWithinCircle(); + + updatePerson(); + removePerson(); + } + + @After + public void tearDown() throws Exception + { + dao.close(); + } + + private void addPersons() + { + dao.createEntityManager(); + for (int i = 0; i < 100; i++) + { + double x = i % 10; + double y = Math.floor(i / 10); + + Person person = new Person(); + person.setPersonId(i + 1); + person.setName("Amresh_" + (i + 1)); + person.setCurrentLocation(new Point(x, y)); + + Vehicle vehicle = new Vehicle(); + vehicle.setCurrentLocation(new Point(x + 1.0, y + 1.0)); + vehicle.setPreviousLocation(new Point(x + 2.0, y + 2.0)); + + person.setVehicle(vehicle); + + dao.addPerson(person); + } + dao.closeEntityManager(); + } + + private void findPerson() + { + dao.createEntityManager(); + Person person = dao.findPerson(4); + + Assert.assertNotNull(person); + Assert.assertEquals(4, person.getPersonId()); + Assert.assertEquals("Amresh_4", person.getName()); + + Point currentLocation = person.getCurrentLocation(); + Assert.assertNotNull(currentLocation); + Assert.assertEquals(3.0, currentLocation.getX()); + Assert.assertEquals(0.0, currentLocation.getY()); + + Vehicle vehicleLocation = person.getVehicle(); + Assert.assertNotNull(vehicleLocation); + Assert.assertNotNull(vehicleLocation.getCurrentLocation()); + Assert.assertEquals(4.0, vehicleLocation.getCurrentLocation().getX()); + Assert.assertEquals(1.0, vehicleLocation.getCurrentLocation().getY()); + Assert.assertNotNull(vehicleLocation.getPreviousLocation()); + Assert.assertEquals(5.0, vehicleLocation.getPreviousLocation().getX()); + Assert.assertEquals(2.0, vehicleLocation.getPreviousLocation().getY()); + + dao.closeEntityManager(); + } + + private void findWithinCircle() + { + dao.createEntityManager(); + + List persons = dao.findWithinCircle(5.0, 5.0, 2.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 13); + dao.closeEntityManager(); + } + + private void findWithinTriangle() + { + dao.createEntityManager(); + + List persons = dao.findWithinTriangle(5.0, 5.0, 6.0, 6.0, 7.0, 7.0); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 3); + dao.closeEntityManager(); + } + + private void findWithinPolygon() + { + dao.createEntityManager(); + + GeometryFactory factory = new GeometryFactory(); + + Coordinate[] coordinates = new Coordinate[6]; + coordinates[0] = new Coordinate(1.0, 1.0); + coordinates[1] = new Coordinate(1.0, 2.0); + coordinates[2] = new Coordinate(3.0, 4, 0); + coordinates[3] = new Coordinate(4.0, 3.0); + coordinates[4] = new Coordinate(4.0, 1.0); + coordinates[5] = new Coordinate(1.0, 1.0); + + CoordinateSequence points = factory.getCoordinateSequenceFactory().create(coordinates); + + LinearRing shell = new LinearRing(points, factory); + LinearRing[] holes = new LinearRing[0]; + // holes[0] = shell; + + Polygon polygon = new Polygon(shell, holes, factory); + List persons = dao.findWithinPolygon(polygon); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 11); + dao.closeEntityManager(); + + dao.createEntityManager(); + + holes = new LinearRing[1]; + holes[0] = shell; + polygon = new Polygon(shell, holes, factory); + persons = dao.findWithinPolygon(polygon); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 8); + dao.closeEntityManager(); + + } + + private void findWithinRectangle() + { + dao.createEntityManager(); + + List persons = dao.findWithinRectangle(5.0, 5.0, 6.0, 6.0); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 4); + dao.closeEntityManager(); + } + + private void findNear() + { + dao.createEntityManager(); + List persons = dao.findNear(5.0, 5.0, 2.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 13); + dao.closeEntityManager(); + } + + private void findNearSphere() + { + dao.createEntityManager(); + List persons = dao.findNear(5.0, 5.0, (2.0 * 2.0 * 3.1416 / 360.0), SurfaceType.SPHERICAL); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 13); + dao.closeEntityManager(); + } + + private void findCentreSphere() + { + dao.createEntityManager(); + + // List persons = dao.findWithinCircle(5.0, 5.0, + // (2.0*2.0*3.1416/360.0), SurfaceType.SPHERICAL); + // Assert.assertNotNull(persons); + // Assert.assertFalse(persons.isEmpty()); + // Assert.assertTrue(persons.size() == 13); + dao.closeEntityManager(); + } + + private void findUsingExactCurrentLocation() + { + dao.createEntityManager(); + + List persons = dao.findUsingCLWithEQ(5.0, 5.0); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 1); + dao.closeEntityManager(); + } + + private void findWithinCircleAndName() + { + dao.createEntityManager(); + + List persons = dao.findWithinCircleAndName(5.0, 5.0, 2.0, SurfaceType.FLAT, "Amresh_45"); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 1); + dao.closeEntityManager(); + } + + private void updateNameWithinCircle() + { + dao.createEntityManager(); + + List persons = dao.updateNameWithinCircle(5.0, 5.0, 0.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 1); + Assert.assertEquals("Kuldeep", persons.get(0).getName()); + dao.closeEntityManager(); + + dao.createEntityManager(); + persons = dao.findWithinCircle(5.0, 5.0, 0.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 1); + Assert.assertEquals("Kuldeep", persons.get(0).getName()); + dao.closeEntityManager(); + } + + private void deleteNameWithinCircle() + { + dao.createEntityManager(); + + List persons = dao.deleteNameWithinCircle(5.0, 5.0, 0.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertFalse(persons.isEmpty()); + Assert.assertTrue(persons.size() == 1); + Assert.assertEquals("Kuldeep", persons.get(0).getName()); + dao.closeEntityManager(); + + dao.createEntityManager(); + persons = dao.findWithinCircle(5.0, 5.0, 0.0, SurfaceType.FLAT); + Assert.assertNotNull(persons); + Assert.assertTrue(persons.isEmpty()); + dao.closeEntityManager(); + } + + /** + * + */ + private void updatePerson() + { + dao.createEntityManager(); + Person person = dao.findPerson(4); + + Assert.assertNotNull(person); + Assert.assertEquals(4, person.getPersonId()); + Assert.assertEquals("Amresh_4", person.getName()); + + person.setCurrentLocation(new Point(9.3, 5.8)); + + Vehicle vehicle = person.getVehicle(); + vehicle.setCurrentLocation(new Point(5.67, 11.59)); + vehicle.setPreviousLocation(new Point(15.67, 21.59)); + + person.setVehicle(vehicle); + + dao.mergePerson(person); + dao.closeEntityManager(); + dao.createEntityManager(); + + person = dao.findPerson(4); + + Assert.assertNotNull(person); + Assert.assertEquals(4, person.getPersonId()); + Assert.assertEquals("Amresh_4", person.getName()); + Point currentLocation = person.getCurrentLocation(); + Assert.assertNotNull(currentLocation); + Assert.assertEquals(9.3, currentLocation.getX()); + Assert.assertEquals(5.8, currentLocation.getY()); + + vehicle = person.getVehicle(); + Assert.assertNotNull(vehicle); + Assert.assertNotNull(vehicle.getCurrentLocation()); + Assert.assertEquals(5.67, vehicle.getCurrentLocation().getX()); + Assert.assertEquals(11.59, vehicle.getCurrentLocation().getY()); + Assert.assertNotNull(vehicle.getPreviousLocation()); + Assert.assertEquals(15.67, vehicle.getPreviousLocation().getX()); + Assert.assertEquals(21.59, vehicle.getPreviousLocation().getY()); + + dao.closeEntityManager(); + + } + + /** + * + */ + private void removePerson() + { + dao.createEntityManager(); + Person person = dao.findPerson(4); + + Assert.assertNotNull(person); + + dao.removePerson(person); + + dao.closeEntityManager(); + dao.createEntityManager(); + + person = dao.findPerson(4); + + Assert.assertNull(person); + dao.closeEntityManager(); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/gis/Person.java b/src/kundera-mongo/src/test/java/com/impetus/client/gis/Person.java new file mode 100644 index 000000000..e5b1ab45f --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/gis/Person.java @@ -0,0 +1,120 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.gis; + +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Person Entity Class + * + * @author amresh.singh + */ + +@Entity +@Table(name = "PERSON_LOCATION", schema = "KunderaExamples@mongoTest") +@IndexCollection(columns = { @Index(name = "currentLocation", type = "GEO2D") }) +public class Person +{ + @Id + @Column(name = "PERSON_ID") + private int personId; + + @Column(name = "PERSON_NAME") + private String name; + + @Column(name = "CURRENT_LOCATION") + private Point currentLocation; + + @Embedded + private Vehicle vehicle; + + /** + * @return the personId + */ + public int getPersonId() + { + return personId; + } + + /** + * @param personId + * the personId to set + */ + public void setPersonId(int personId) + { + this.personId = personId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the currentLocation + */ + public Point getCurrentLocation() + { + return currentLocation; + } + + /** + * @param currentLocation + * the currentLocation to set + */ + public void setCurrentLocation(Point currentLocation) + { + this.currentLocation = currentLocation; + } + + /** + * @return the vehicle + */ + public Vehicle getVehicle() + { + return vehicle; + } + + /** + * @param vehicle + * the vehicle to set + */ + public void setVehicle(Vehicle vehicle) + { + this.vehicle = vehicle; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/gis/PersonGISDao.java b/src/kundera-mongo/src/test/java/com/impetus/client/gis/PersonGISDao.java new file mode 100644 index 000000000..85ea11dad --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/gis/PersonGISDao.java @@ -0,0 +1,233 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.gis; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import com.impetus.client.utils.MongoUtils; +import com.impetus.kundera.gis.SurfaceType; +import com.impetus.kundera.gis.geometry.Circle; +import com.impetus.kundera.gis.geometry.Envelope; +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.gis.geometry.Polygon; +import com.impetus.kundera.gis.geometry.Triangle; + +/** + * DAO for Geolocation processing for {@link Person} entity + * + * @author amresh.singh + */ +public class PersonGISDao +{ + + private EntityManager em; + + private EntityManagerFactory emf; + + private String pu; + + public PersonGISDao(String persistenceUnitName) + { + this.pu = persistenceUnitName; + if (emf == null) + { + try + { + emf = Persistence.createEntityManagerFactory(persistenceUnitName); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + } + + public void createEntityManager() + { + if (em == null) + { + em = emf.createEntityManager(); + } + } + + public void closeEntityManager() + { + if (em != null) + { + em.close(); + em = null; + } + } + + public void close() + { + if (emf != null) + { + MongoUtils.dropDatabase(emf, pu); + emf.close(); + } + } + + public void addPerson(Person person) + { + em.persist(person); + } + + public Person findPerson(int personId) + { + return em.find(Person.class, personId); + } + + public List findWithinCircle(double x, double y, double r, SurfaceType surfaceType) + { + Circle circle = new Circle(x, y, r); + circle.setSurfaceType(surfaceType); + + Query q = em.createQuery("Select p from Person p where p.currentLocation IN ?1"); + q.setParameter(1, circle); + List persons = q.getResultList(); + return persons; + } + + public List findWithinTriangle(double x1, double y1, double x2, double y2, double x3, double y3) + { + + Triangle triangle = new Triangle(x1, y1, x2, y2, x3, y3); + + Query q = em.createQuery("Select p from Person p where p.currentLocation IN :triangle"); + q.setParameter("triangle", triangle); + List persons = q.getResultList(); + return persons; + } + + public List findWithinPolygon(Polygon polygon) + { + Query q = em.createQuery("Select p from Person p where p.currentLocation IN :polygon"); + q.setParameter("polygon", polygon); + List persons = q.getResultList(); + return persons; + } + + public List findWithinRectangle(double x1, double y1, double x2, double y2) + { + Envelope envelope = new Envelope(x1, x2, y1, y2); + Query q = em.createQuery("Select p from Person p where p.currentLocation IN :envelope"); + q.setParameter("envelope", envelope); + List persons = q.getResultList(); + return persons; + } + + public List findNear(double x, double y, double maxDistance, SurfaceType surfaceType) + { + Point point = new Point(x, y); + point.setSurfaceType(surfaceType); + + Query q = em + .createQuery("Select p from Person p where p.currentLocation > :point AND p.currentLocation < :maxDistance"); + q.setParameter("point", point); + q.setParameter("maxDistance", maxDistance); + List persons = q.getResultList(); + return persons; + } + + public void mergePerson(Person person) + { + em.merge(person); + } + + public void removePerson(Person person) + { + em.remove(person); + } + + /** + * @param d + * @param e + * @return + */ + public List findUsingCLWithEQ(double x, double y) + { + Circle circle = new Circle(x, y, 0); + circle.setSurfaceType(SurfaceType.FLAT); + + Query q = em.createQuery("Select p from Person p where p.currentLocation IN ?1"); + q.setParameter(1, circle); + List persons = q.getResultList(); + return persons; + } + + /** + * @param d + * @param e + * @param f + * @param flat + * @param string + * @return + */ + public List findWithinCircleAndName(double x, double y, double r, SurfaceType surfaceType, String name) + { + + Circle circle = new Circle(x, y, r); + circle.setSurfaceType(surfaceType); + + Query q = em.createQuery("Select p from Person p where p.name = :name and p.currentLocation IN :circle"); + q.setParameter("name", name); + q.setParameter("circle", circle); + List persons = q.getResultList(); + return persons; + + } + + /** + * @param d + * @param e + * @param f + * @param flat + * @return + */ + public List updateNameWithinCircle(double x, double y, double r, SurfaceType surfaceType) + { + Circle circle = new Circle(x, y, r); + circle.setSurfaceType(surfaceType); + Query q = em.createQuery("Update Person p SET p.name=Kuldeep where p.currentLocation IN ?1"); + q.setParameter(1, circle); + List persons = q.getResultList(); + return persons; + } + + /** + * @param d + * @param e + * @param f + * @param flat + * @return + */ + public List deleteNameWithinCircle(double x, double y, double r, SurfaceType surfaceType) + { + Circle circle = new Circle(x, y, r); + circle.setSurfaceType(surfaceType); + Query q = em.createQuery("Delete From Person p where p.currentLocation IN ?1"); + q.setParameter(1, circle); + List persons = q.getResultList(); + return persons; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/gis/Vehicle.java b/src/kundera-mongo/src/test/java/com/impetus/client/gis/Vehicle.java new file mode 100644 index 000000000..734a011b6 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/gis/Vehicle.java @@ -0,0 +1,74 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.gis; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * @author Kuldeep Mishra + * + */ +@Embeddable +@IndexCollection(columns = { @Index(name = "currentLocation", type = "GEO2D"), + @Index(name = "previousLocation", type = "GEO2D") }) +public class Vehicle +{ + @Column(name = "CURRENT_VEHICLE_LOCATION") + private Point currentLocation; + + @Column(name = "PREVIOUS_VEHICLE_LOCATION") + private Point previousLocation; + + /** + * @return the currentLocation + */ + public Point getCurrentLocation() + { + return currentLocation; + } + + /** + * @param currentLocation + * the currentLocation to set + */ + public void setCurrentLocation(Point currentLocation) + { + this.currentLocation = currentLocation; + } + + /** + * @return the previousLocation + */ + public Point getPreviousLocation() + { + return previousLocation; + } + + /** + * @param previousLocation + * the previousLocation to set + */ + public void setPreviousLocation(Point previousLocation) + { + this.previousLocation = previousLocation; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoDBPropertyReaderTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoDBPropertyReaderTest.java new file mode 100644 index 000000000..1877cd421 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoDBPropertyReaderTest.java @@ -0,0 +1,206 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb.config; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBConstants; +import com.impetus.client.mongodb.config.MongoDBPropertyReader.MongoDBSchemaMetadata; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.configure.PersistenceUnitConfiguration; +import com.impetus.kundera.configure.PropertyReader; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.mongodb.ReadPreference; + +/** + * @author impadmin + * + */ +public class MongoDBPropertyReaderTest +{ + + private static Logger log = LoggerFactory.getLogger(MongoDBPropertyReaderTest.class); + + private List connections = new ArrayList(); + + private String pu = "mongoTest"; + + private MongoDBSchemaMetadata dbSchemaMetadata; + + private int timeOut; + + private ReadPreference readPreference; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + new PersistenceUnitConfiguration(pu).configure(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + /** + * Test method for + * {@link com.impetus.client.mongodb.config.MongoDBPropertyReader#read(java.lang.String)} + * . + */ + @Test + public void testRead() + { + PropertyReader reader = new MongoDBPropertyReader(null); + reader.read(pu); + dbSchemaMetadata = MongoDBPropertyReader.msmd; + + Properties properties = new Properties(); + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(pu); + String propertyName = puMetadata != null ? puMetadata + .getProperty(PersistenceProperties.KUNDERA_CLIENT_PROPERTY) : null; + + InputStream inStream = propertyName != null ? ClassLoader.getSystemResourceAsStream(propertyName) : null; + if (inStream != null) + { + try + { + properties.load(inStream); + String readPreference = properties.getProperty(MongoDBConstants.READ_PREFERENCE); + if (readPreference != null) + { + if (readPreference.equalsIgnoreCase("primary")) + { + this.readPreference = ReadPreference.PRIMARY; + } + else if (readPreference.equalsIgnoreCase("secondary")) + { + this.readPreference = ReadPreference.SECONDARY; + } + else + { + log.warn("Incorrect Read Preference specified. Only primary/ secondary allowed"); + } + } + timeOut = Integer.parseInt(properties.getProperty(MongoDBConstants.SOCKET_TIMEOUT)); + + parseConnectionString(properties.getProperty(MongoDBConstants.CONNECTIONS)); + + // Assert.assertEquals(timeOut, + // dbSchemaMetadata.getSocketTimeOut()); + // Assert.assertEquals(this.readPreference, + // dbSchemaMetadata.getReadPreference()); + // Assert.assertEquals(connections.size(), + // dbSchemaMetadata.getConnections().size()); + } + catch (NumberFormatException nfe) + { + log.info("time out should be numeric"); + } + catch (IOException e) + { + log.info("property file not found in class path"); + } + } + } + + private void parseConnectionString(String connectionStr) + { + String[] tokens = { "host", "port" }; + Map hostPort = new HashMap(); + // parse connectionStr + StringTokenizer connections = new StringTokenizer(connectionStr, ","); + while (connections.hasMoreTokens()) + { + StringTokenizer connection = new StringTokenizer(connections.nextToken(), ":"); + int count = 0; + while (connection.hasMoreTokens()) + { + hostPort.put(tokens[count++], connection.nextToken()); + } + addConnection(hostPort.get(tokens[0]), hostPort.get(tokens[1])); + } + } + + private void addConnection(String host, String port) + { + Connection connection = null; + if (host != null && port != null) + { + connection = new Connection(host, port); + } + else + { + // TODO + return; + } + + if (connection != null && !connections.contains(connection)) + { + connections.add(connection); + } + } + + private class Connection + { + private String host; + + private String port; + + public Connection(String host, String port) + { + this.host = host; + this.port = port; + } + + /** + * @return the host + */ + public String getHost() + { + return host; + } + + /** + * @return the port + */ + public String getPort() + { + return port; + } + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUser.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUser.java new file mode 100644 index 000000000..a9c2bb1ef --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUser.java @@ -0,0 +1,80 @@ +/** + * + */ +package com.impetus.client.mongodb.config; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "MongoUser", schema = "KunderaCassandraXmlTest@mongoTest") +public class MongoUser +{ + + @Id + private String name; + + @Column + private int age; + + @Column + private String address; + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the age + */ + public int getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(int age) + { + this.age = age; + } + + /** + * @return the address + */ + public String getAddress() + { + return address; + } + + /** + * @param address + * the address to set + */ + public void setAddress(String address) + { + this.address = address; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUserTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUserTest.java new file mode 100644 index 000000000..8abd41166 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/MongoUserTest.java @@ -0,0 +1,75 @@ +/** + * + */ +package com.impetus.client.mongodb.config; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * @author Kuldeep Mishra + * + */ +public class MongoUserTest +{ + + /** + * + */ + private static final String _PU = "mongoTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + private Map puProperties = new HashMap(); + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + puProperties.put("kundera.ddl.auto.prepare", "create-drop"); + puProperties.put("kundera.keyspace", "KunderaMongoKeyspace"); + emf = Persistence.createEntityManagerFactory(_PU, puProperties); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + puProperties = null; + } + + @Test + public void test() + { + MongoUser u = new MongoUser(); + u.setName("kuldeep"); + u.setAge(24); + u.setAddress("gzb"); + em.persist(u); + + em.clear(); + + MongoUser user = em.find(MongoUser.class, "kuldeep"); + Assert.assertNotNull(user); + Assert.assertEquals(24, user.getAge()); + Assert.assertEquals("gzb", user.getAddress()); + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/OperationLevelPropertiesTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/OperationLevelPropertiesTest.java new file mode 100644 index 000000000..51d81c872 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/config/OperationLevelPropertiesTest.java @@ -0,0 +1,120 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.mongodb.config; + +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.crud.PersonMongo; +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.mongodb.MongoDBClientProperties; +import com.impetus.kundera.client.Client; +import com.mongodb.DBEncoder; +import com.mongodb.DefaultDBEncoder; +import com.mongodb.LazyDBEncoder; +import com.mongodb.WriteConcern; + +/** + * Test case for properties set on operation level in MongoDBClient + * + * @author amresh.singh + */ +public class OperationLevelPropertiesTest +{ + String persistenceUnit = "mongoTest"; + + EntityManagerFactory emf; + + EntityManager em; + + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + em.getDelegate(); + } + + @Test + public void executeTest() + { + // Get properties from client + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get(persistenceUnit); + + // Check default values + WriteConcern wc = client.getWriteConcern(); + DBEncoder encoder = client.getEncoder(); + Assert.assertNotNull(wc); + Assert.assertFalse(wc.getFsync()); + Assert.assertEquals(0, wc.getW()); + Assert.assertEquals(0, wc.getWtimeout()); + Assert.assertNotNull(encoder); + Assert.assertTrue(encoder instanceof DefaultDBEncoder); + + // Set parameters into EM + // (See http://api.mongodb.org/java/2.6/com/mongodb/WriteConcern.html) + WriteConcern wcNew = new WriteConcern(1, 300, true); + DBEncoder encoderNew = new LazyDBEncoder(); + em.setProperty(MongoDBClientProperties.WRITE_CONCERN, wcNew); + // em.setProperty(MongoDBClientProperties.DB_ENCODER, encoderNew); + + // Check Modified values + WriteConcern wcModified = client.getWriteConcern(); + DBEncoder encoderModified = client.getEncoder(); + Assert.assertNotNull(wcModified); + Assert.assertTrue(wcModified.getFsync()); + Assert.assertEquals(1, wcModified.getW()); + Assert.assertEquals(300, wcModified.getWtimeout()); + Assert.assertNotNull(encoderModified); + // Assert.assertTrue(encoderModified instanceof LazyDBEncoder); + + // Write Entity to database + PersonMongo person = new PersonMongo(); + person.setPersonId("1"); + person.setPersonName("Amresh"); + person.setAge(31); + em.persist(person); + + // Find entity from database + PersonMongo p = em.find(PersonMongo.class, "1"); + Assert.assertNotNull(p); + + // Delete entity from database + em.remove(p); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + em.close(); + emf.close(); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/index/IndexTypeTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/index/IndexTypeTest.java new file mode 100644 index 000000000..5c610d572 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/index/IndexTypeTest.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * * Copyright 2013 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb.index; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * @author amresh.singh + * + */ +public class IndexTypeTest +{ + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + /** + * Test method for {@link com.impetus.client.mongodb.index.IndexType#findByValue(com.impetus.client.mongodb.index.IndexType)}. + */ + @Test + public void testFindByValue() + { + Assert.assertEquals("1", IndexType.findByValue(IndexType.ASC)); + Assert.assertEquals("-1", IndexType.findByValue(IndexType.DSC)); + Assert.assertEquals("2D", IndexType.findByValue(IndexType.GEO2D)); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBEntitySimple.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBEntitySimple.java new file mode 100644 index 000000000..d1eefa7d3 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBEntitySimple.java @@ -0,0 +1,142 @@ +/** + * + */ +package com.impetus.client.mongodb.schemamanager; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.impetus.kundera.gis.geometry.Point; +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * @author Kuldeep Mishra + * + */ +@Entity +@Table(name = "MongoDBEntitySimple", schema = "KunderaMongoSchemaGeneration@mongoSchemaGenerationTest") +@IndexCollection(columns = { @Index(name = "personName", type = "ASC"), + @Index(name = "age", type = "DSC", min = 100, max = 500), + @Index(name = "currentLocation", type = "GEO2D", min = -100, max = 500) }) +public class MongoDBEntitySimple +{ + + /** The person id. */ + @Id + @Column(name = "PERSON_ID") + private String personId; + + /** The person name. */ + @Column(name = "PERSON_NAME") + private String personName; + + /** The age. */ + @Column(name = "AGE") + private short age; + + @Column(name = "CURRENT_LOCATION") + private Point currentLocation; + + @Column(name = "PREVIOUS_LOCATION") + private Point previousLocation; + + /** + * Gets the person id. + * + * @return the person id + */ + public String getPersonId() + { + return personId; + } + + /** + * Gets the person name. + * + * @return the person name + */ + public String getPersonName() + { + return personName; + } + + /** + * Sets the person name. + * + * @param personName + * the new person name + */ + public void setPersonName(String personName) + { + this.personName = personName; + } + + /** + * Sets the person id. + * + * @param personId + * the new person id + */ + public void setPersonId(String personId) + { + this.personId = personId; + } + + /** + * Gets the age. + * + * @return the age + */ + public short getAge() + { + return age; + } + + /** + * Sets the age. + * + * @param age + * the age to set + */ + public void setAge(short age) + { + this.age = age; + } + + /** + * @return the currentLocation + */ + public Point getCurrentLocation() + { + return currentLocation; + } + + /** + * @param currentLocation + * the currentLocation to set + */ + public void setCurrentLocation(Point currentLocation) + { + this.currentLocation = currentLocation; + } + + /** + * @return the previousLocation + */ + public Point getPreviousLocation() + { + return previousLocation; + } + + /** + * @param previousLocation + * the previousLocation to set + */ + public void setPreviousLocation(Point previousLocation) + { + this.previousLocation = previousLocation; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManagerTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManagerTest.java new file mode 100644 index 000000000..52c04ddb6 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/mongodb/schemamanager/MongoDBSchemaManagerTest.java @@ -0,0 +1,268 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.mongodb.schemamanager; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.client.mongodb.MongoDBClientFactory; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.configure.schema.SchemaGenerationException; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBCollection; +import com.mongodb.DBObject; +import com.mongodb.ReadPreference; + +/** + * @author Kuldeep Mishra + * + */ +public class MongoDBSchemaManagerTest +{ + private DB db; + + private String persistenceUnit = "mongoSchemaGenerationTest"; + + private EntityManagerFactory emf; + + private EntityManager em; + + + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + truncateMongo(); + } + + + @Test + public void testValidate() + { + + try + { + Map props = new HashMap(); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "validate"); + emf = Persistence.createEntityManagerFactory(persistenceUnit, props); + Assert.fail("Schema generation exception should have been thrown since schema doesn't exist"); + } + catch (Exception e) + { + Assert.assertNotNull(e); + } + } + + @Test + public void testUpdate() + { + + Map props = new HashMap(); + props.put(PersistenceProperties.KUNDERA_DDL_AUTO_PREPARE, "update"); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + emf = Persistence.createEntityManagerFactory(persistenceUnit, props); + em = emf.createEntityManager(); + + getDB(); + + DBCollection collection = db.getCollection("MongoDBEntitySimple"); + Assert.assertEquals(ReadPreference.PRIMARY, collection.getReadPreference()); + Assert.assertNotNull(collection.getIndexInfo()); + Assert.assertEquals(4, collection.getIndexInfo().size()); + int count = 0; + for (DBObject dbObject : collection.getIndexInfo()) + { + + if (dbObject.get("name").equals("_id_")) + { + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("_id", 1))); + count++; + } + else if (dbObject.get("name").equals("PERSON_NAME_1")) + { + Assert.assertEquals(new Integer(Integer.MIN_VALUE), dbObject.get("min")); + Assert.assertEquals(new Integer(Integer.MAX_VALUE), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("PERSON_NAME", 1))); + count++; + } + else if (dbObject.get("name").equals("AGE_-1")) + { + Assert.assertEquals(new Integer(100), dbObject.get("min")); + Assert.assertEquals(new Integer(500), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("AGE", -1))); + count++; + } + else + { + Assert.assertEquals(new Integer(-100), dbObject.get("min")); + Assert.assertEquals(new Integer(500), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("CURRENT_LOCATION", "2d"))); + count++; + } + } + Assert.assertEquals(4, count); + } + + /** + * Test method for + * {@link com.impetus.client.mongodb.schemamanager.MongoDBSchemaManager#create(java.util.List)} + * . + */ + @Test + public void testCreate() + { + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + getDB(); + + DBCollection collection = db.getCollection("MongoDBEntitySimple"); + Assert.assertEquals(ReadPreference.PRIMARY, collection.getReadPreference()); + Assert.assertNotNull(collection.getIndexInfo()); + Assert.assertEquals(4, collection.getIndexInfo().size()); + int count = 0; + for (DBObject dbObject : collection.getIndexInfo()) + { + + if (dbObject.get("name").equals("_id_")) + { + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("_id", 1))); + count++; + } + else if (dbObject.get("name").equals("PERSON_NAME_1")) + { + Assert.assertEquals(new Integer(Integer.MIN_VALUE), dbObject.get("min")); + Assert.assertEquals(new Integer(Integer.MAX_VALUE), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("PERSON_NAME", 1))); + count++; + } + else if (dbObject.get("name").equals("AGE_-1")) + { + Assert.assertEquals(new Integer(100), dbObject.get("min")); + Assert.assertEquals(new Integer(500), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("AGE", -1))); + count++; + } + else + { + Assert.assertEquals(new Integer(-100), dbObject.get("min")); + Assert.assertEquals(new Integer(500), dbObject.get("max")); + Assert.assertTrue(dbObject.get("key").equals(new BasicDBObject("CURRENT_LOCATION", "2d"))); + count++; + } + } + Assert.assertEquals(4, count); + } + + /** + * Test method for + * {@link com.impetus.client.mongodb.schemamanager.MongoDBSchemaManager#dropSchema()} + * . + */ + @Test + public void testDropSchema() + { + emf = Persistence.createEntityManagerFactory(persistenceUnit); + em = emf.createEntityManager(); + getDB(); + + MongoDBClientFactory clientFactory = (MongoDBClientFactory) ClientResolver.getClientFactory(persistenceUnit); + clientFactory.getSchemaManager(null).dropSchema(); + DBCollection collection = db.getCollection("MongoDBEntitySimple"); + Assert.assertTrue(collection.getIndexInfo().isEmpty()); + Assert.assertEquals(0,collection.getCount()); + } + + /** + * + */ + private void truncateMongo() + { + + if (db != null) + { + db.dropDatabase(); + } + } + + /** + * + */ + private void getDB() + { + Map clients = (Map) em.getDelegate(); + MongoDBClient client = (MongoDBClient) clients.get(persistenceUnit); + if (client != null) + { + try + { + Field mongodb = client.getClass().getDeclaredField("mongoDb"); + if (!mongodb.isAccessible()) + { + mongodb.setAccessible(true); + } + db = (DB) mongodb.get(client); + } + + catch (SecurityException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (NoSuchFieldException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalArgumentException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + catch (IllegalAccessException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwingoTest.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwingoTest.java new file mode 100644 index 000000000..3ab26e8c3 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwingoTest.java @@ -0,0 +1,99 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import org.databene.contiperf.PerfTest; +import org.databene.contiperf.junit.ContiPerfRule; +import org.databene.contiperf.report.CSVSummaryReportModule; +import org.databene.contiperf.report.HtmlReportModule; +import org.databene.contiperf.report.ReportModule; +import org.junit.Rule; +import org.junit.Test; + +import com.impetus.client.twitter.dao.Twitter; + +/** + * Test case for MongoDB. + * + * @author amresh.singh + */ +public class TwingoTest extends TwitterTestBaseMongo +{ + + /** The user id1. */ + String userId1; + + /** The user id2. */ + String userId2; + + /** The twitter. */ + Twitter twitter; + + @Rule + public ContiPerfRule i = new ContiPerfRule(new ReportModule[] { new CSVSummaryReportModule(), + new HtmlReportModule() }); + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception + { + setUpInternal("mongoTest"); + } + + /** + * Test on execute. + */ + + @Test + @PerfTest(invocations = 10) + public void testOnExecute() + { + executeTestSuite(); + } + + @Override + protected void tearDown() throws Exception + { + tearDownInternal(); + } + + @Override + void createSchema() + { + // No need to create schema, it will be created automatically + } + + @Override + void startServer() + { + // Currently no embedded server + } + + @Override + void stopServer() + { + // Currently no embedded server + } + + @Override + void deleteSchema() + { + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwitterTestBaseMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwitterTestBaseMongo.java new file mode 100644 index 000000000..32cf1860b --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/TwitterTestBaseMongo.java @@ -0,0 +1,489 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter; + +import java.util.List; + +import junit.framework.TestCase; + +import org.junit.Assert; + +import com.impetus.client.twitter.dao.Twitter; +import com.impetus.client.twitter.dao.TwitterService; +import com.impetus.client.twitter.entities.ExternalLinkMongo; +import com.impetus.client.twitter.entities.PersonalDetailMongo; +import com.impetus.client.twitter.entities.PreferenceMongo; +import com.impetus.client.twitter.entities.TweetMongo; +import com.impetus.client.twitter.entities.UserMongo; + +/** + * Test case for MongoDB. + * + * @author amresh.singh + */ +public abstract class TwitterTestBaseMongo extends TestCase +{ + public static final boolean RUN_IN_EMBEDDED_MODE = true; + + public static final boolean AUTO_MANAGE_SCHEMA = true; + + /** The user id1. */ + String userId1; + + /** The user id2. */ + String userId2; + + /** The twitter. */ + protected Twitter twitter; + + /** + * Sets the up internal. + * + * @param persistenceUnitName + * the new up internal + * @throws Exception + * the exception + */ + protected void setUpInternal(String persistenceUnitName) throws Exception + { + userId1 = "0001"; + userId2 = "0002"; + + // Start Cassandra Server + if (RUN_IN_EMBEDDED_MODE) + { + startServer(); + } + + twitter = new TwitterService(persistenceUnitName); + + // Create Schema + if (AUTO_MANAGE_SCHEMA) + { + createSchema(); + } + } + + /* + * (non-Javadoc) + * + * @see junit.framework.TestCase#tearDown() + */ + /** + * Tear down internal. + * + * @throws Exception + * the exception + */ + protected void tearDownInternal() throws Exception + { + if (twitter != null) + { + twitter.close(); + } + + if (AUTO_MANAGE_SCHEMA) + { + deleteSchema(); + } + + // Stop Server + if (RUN_IN_EMBEDDED_MODE) + { + stopServer(); + } + } + + /** + * Execute suite. + */ + protected void executeTestSuite() + { + // Insert, Find and Update + addAllUserInfo(); + getUserById(); + updateUser(); + + // Queries + getAllUsers(); + getAllTweets(); + + // Remove Users + removeUser(); + + } + + protected void addAllUserInfo() + { + UserMongo user1 = buildUser1(); + UserMongo user2 = buildUser2(); + + twitter.createEntityManager(); + twitter.addUser(user1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(user2); + twitter.closeEntityManager(); + } + + protected void getUserById() + { + twitter.createEntityManager(); + UserMongo user1 = twitter.findUserById(userId1); + assertUser1(user1); + + UserMongo user2 = twitter.findUserById(userId2); + assertUser2(user2); + + } + + protected void updateUser() + { + twitter.createEntityManager(); + UserMongo user1 = twitter.findUserById(userId1); + assertUser1(user1); + + user1.setPersonalDetail(new PersonalDetailMongo("Vivek", "unknown", "Married")); + user1.addTweet(new TweetMongo("My Third Tweet", "iPhone")); + twitter.mergeUser(user1); + + UserMongo user1AfterMerge = twitter.findUserById(userId1); + + assertUpdatedUser1(user1AfterMerge); + + twitter.closeEntityManager(); + } + + protected void removeUser() + { + twitter.createEntityManager(); + UserMongo user1 = twitter.findUserById(userId1); + // TODO: this needs to uncomment only after fixing update issue on + // associations + // assertUpdatedUser1(user1); + + twitter.removeUser(user1); + + UserMongo user1AfterRemoval = twitter.findUserById(userId1); + Assert.assertNull(user1AfterRemoval); + + UserMongo user2 = twitter.findUserById(userId2); + // TODO: this needs to uncomment only after fixing update issue on + // associations + // assertUpdatedUser1(user1); + + twitter.removeUser(user2); + + UserMongo user2AfterRemoval = twitter.findUserById(userId2); + Assert.assertNull(user2AfterRemoval); + + twitter.closeEntityManager(); + + } + + protected void getAllUsers() + { + twitter.createEntityManager(); + List users = twitter.getAllUsers(); + Assert.assertNotNull(users); + Assert.assertFalse(users.isEmpty()); + Assert.assertEquals(2, users.size()); + + for (UserMongo u : users) + { + Assert.assertNotNull(u); + if (u.getUserId().equals(userId1)) + { + // TODO: this needs to uncomment only after fixing update issue + // on associations + // assertUpdatedUser1(u); + } + else if (u.getUserId().equals(userId2)) + { + // assertUser2(u); + } + } + twitter.closeEntityManager(); + } + + /** + * Adds the users. + */ + protected void addUsers() + { + twitter.createEntityManager(); + twitter.addUser(userId1, "Amresh", "password1", "married"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addUser(userId2, "Saurabh", "password2", "single"); + twitter.closeEntityManager(); + } + + /** + * Save preference. + */ + protected void savePreference() + { + twitter.createEntityManager(); + twitter.savePreference(userId1, new PreferenceMongo("P1", "Motif", "2")); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.savePreference(userId2, new PreferenceMongo("P2", "High Contrast", "3")); + twitter.closeEntityManager(); + } + + /** + * Adds the external links. + */ + protected void addExternalLinks() + { + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L1", "Facebook", "http://facebook.com/coolnerd"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId1, "L2", "LinkedIn", "http://linkedin.com/in/devilmate"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L3", "GooglePlus", "http://plus.google.com/inviteme"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addExternalLink(userId2, "L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry"); + twitter.closeEntityManager(); + } + + /** + * Adds the tweets. + */ + protected void addTweets() + { + twitter.createEntityManager(); + twitter.addTweet(userId1, "Here is my first tweet", "Web"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId1, "Second Tweet from me", "Mobile"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Saurabh tweets for the first time", "Phone"); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + twitter.addTweet(userId2, "Another tweet from Saurabh", "text"); + twitter.closeEntityManager(); + } + + /** + * User1 follows user2. + */ + protected void user1FollowsUser2() + { + twitter.createEntityManager(); + twitter.startFollowing(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * User1 adds user2 as follower. + */ + protected void user1AddsUser2AsFollower() + { + twitter.createEntityManager(); + twitter.addFollower(userId1, userId2); + twitter.closeEntityManager(); + } + + /** + * Gets the all tweets. + * + * @return the all tweets + */ + protected void getAllTweets() + { + twitter.createEntityManager(); + + List tweetsUser1 = twitter.getAllTweets(userId1); + List tweetsUser2 = twitter.getAllTweets(userId2); + + twitter.closeEntityManager(); + + assertNotNull(tweetsUser1); + assertNotNull(tweetsUser2); + + assertFalse(tweetsUser1.isEmpty()); + assertFalse(tweetsUser2.isEmpty()); + + // TODO : uncomment + assertEquals(3, tweetsUser1.size()); + // assertEquals(2, tweetsUser1.size()); + assertEquals(2, tweetsUser2.size()); + } + + /** + * Gets the tweets by body. + * + * @return the tweets by body + */ + public void getTweetsByBody() + { + twitter.createEntityManager(); + List user1Tweet = twitter.findTweetByBody("Here"); + List user2Tweet = twitter.findTweetByBody("Saurabh"); + + twitter.closeEntityManager(); + + assertNotNull(user1Tweet); + assertNotNull(user2Tweet); + assertEquals(1, user1Tweet.size()); + assertEquals(1, user2Tweet.size()); + } + + /** + * Gets the tweet by device. + * + * @return the tweet by device + */ + public void getTweetsByDevice() + { + twitter.createEntityManager(); + List webTweets = twitter.findTweetByDevice("Web"); + List mobileTweets = twitter.findTweetByDevice("Mobile"); + + twitter.closeEntityManager(); + + assertNotNull(webTweets); + assertNotNull(mobileTweets); + assertEquals(1, webTweets.size()); + assertEquals(1, mobileTweets.size()); + + } + + /** + * Gets the all followers. + * + * @return the all followers + */ + protected void getAllFollowers() + { + twitter.createEntityManager(); + List follower1 = twitter.getFollowers(userId1); + twitter.closeEntityManager(); + + twitter.createEntityManager(); + List follower2 = twitter.getFollowers(userId2); + twitter.closeEntityManager(); + + assertNull(follower1); + assertNotNull(follower2); + } + + /** + * @return + */ + private UserMongo buildUser1() + { + UserMongo user1 = new UserMongo(userId1, "Amresh", "password1", "married"); + + user1.setPreference(new PreferenceMongo("P1", "Motif", "2")); + + user1.addExternalLink(new ExternalLinkMongo("L1", "Facebook", "http://facebook.com/coolnerd")); + user1.addExternalLink(new ExternalLinkMongo("L2", "LinkedIn", "http://linkedin.com/in/devilmate")); + + user1.addTweet(new TweetMongo("Here is my first tweet", "Web")); + user1.addTweet(new TweetMongo("Second Tweet from me", "Mobile")); + return user1; + } + + /** + * @return + */ + private UserMongo buildUser2() + { + UserMongo user2 = new UserMongo(userId2, "Saurabh", "password2", "single"); + + user2.setPreference(new PreferenceMongo("P2", "High Contrast", "3")); + + user2.addExternalLink(new ExternalLinkMongo("L3", "GooglePlus", "http://plus.google.com/inviteme")); + user2.addExternalLink(new ExternalLinkMongo("L4", "Yahoo", "http://yahoo.com/profiles/itsmeamry")); + + user2.addTweet(new TweetMongo("Saurabh tweets for the first time", "Phone")); + user2.addTweet(new TweetMongo("Another tweet from Saurabh", "text")); + return user2; + } + + private void assertUser1(UserMongo user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Amresh", user1.getPersonalDetail().getName()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(2, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + private void assertUser2(UserMongo user2) + { + Assert.assertNotNull(user2); + Assert.assertEquals(userId2, user2.getUserId()); + Assert.assertNotNull(user2.getPersonalDetail()); + Assert.assertEquals("Saurabh", user2.getPersonalDetail().getName()); + Assert.assertNotNull(user2.getPreference()); + Assert.assertEquals("3", user2.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user2.getTweets()); + Assert.assertFalse(user2.getTweets().isEmpty()); + Assert.assertEquals(2, user2.getTweets().size()); + Assert.assertNotNull(user2.getExternalLinks()); + Assert.assertFalse(user2.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user2.getExternalLinks().size()); + } + + private void assertUpdatedUser1(UserMongo user1) + { + Assert.assertNotNull(user1); + Assert.assertEquals(userId1, user1.getUserId()); + Assert.assertNotNull(user1.getPersonalDetail()); + Assert.assertEquals("Vivek", user1.getPersonalDetail().getName()); + Assert.assertEquals("unknown", user1.getPersonalDetail().getPassword()); + Assert.assertNotNull(user1.getPreference()); + Assert.assertEquals("2", user1.getPreference().getPrivacyLevel()); + Assert.assertNotNull(user1.getTweets()); + Assert.assertFalse(user1.getTweets().isEmpty()); + Assert.assertEquals(3, user1.getTweets().size()); + Assert.assertNotNull(user1.getExternalLinks()); + Assert.assertFalse(user1.getExternalLinks().isEmpty()); + Assert.assertEquals(2, user1.getExternalLinks().size()); + } + + abstract void startServer(); + + abstract void stopServer(); + + abstract void deleteSchema(); + + abstract void createSchema(); +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/SuperDao.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/SuperDao.java new file mode 100644 index 000000000..8aa64826e --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/SuperDao.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +/** + * The Class SuperDao. + * + * @author impetus + */ +public class SuperDao +{ + + /** + * Inits the. + * + * @param persistenceUnitName + * the persistence unit name + * @return the entity manager + * @throws Exception + * the exception + */ + protected EntityManagerFactory createEntityManagerFactory(String persistenceUnitName) + { + return Persistence.createEntityManagerFactory(persistenceUnitName); + + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/Twitter.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/Twitter.java new file mode 100644 index 000000000..4d82605d6 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/Twitter.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.util.List; + +import com.impetus.client.twitter.entities.PreferenceMongo; +import com.impetus.client.twitter.entities.TweetMongo; +import com.impetus.client.twitter.entities.UserMongo; + +/** + * Single window application for Twitter application. Contains methods for + * performing CRUD operations on users and their tweets. + */ +public interface Twitter +{ + + void addUser(UserMongo user); + + /** + * Registers a new user with Twitter application + * + * @param userId + * the user id + * @param name + * the name + * @param password + * the password + * @param relationshipStatus + * the relationship status + */ + void addUser(String userId, String name, String password, String relationshipStatus); + + /** + * Save preference for a given user + * + * @param userId + * the user id + * @param preference + * the preference + */ + void savePreference(String userId, PreferenceMongo preference); + + /** + * Adds an external link for the given user + * + * @param userId + * the user id + * @param linkType + * the link type + * @param linkAddress + * the link address + */ + void addExternalLink(String userId, String linkId, String linkType, String linkAddress); + + /** + * Adds a new tweet for a user + * + * @param userId + * the user id + * @param tweetBody + * the tweet body + * @param device + * the device + */ + void addTweet(String userId, String tweetBody, String device); + + /** + * Makes User whose row key is userId follow a user whose row + * key is friendUserId + * + * @param userId + * the user id + * @param friendUserId + * the friend user id + */ + void startFollowing(String userId, String friendUserId); + + /** + * Adds the follower whose row key is followerUserId to User + * whose row key is userId + * + * @param userId + * the user id + * @param followerUserId + * the follower user id + */ + void addFollower(String userId, String followerUserId); + + UserMongo findUserById(String userId); + + void removeUser(UserMongo user); + + void mergeUser(UserMongo user); + + /** + * Retrieves all tweets for a given user + * + * @param userId + * the user id + * @return the all tweets + */ + List getAllUsers(); + + List getAllTweets(String userId); + + /** + * Returns a list of followers for a given user. + * + * @param userId + * user id + * @return list of all followers. + */ + List getFollowers(String userId); + + /** + * Find tweet by tweet body. + * + * @param tweetBody + * the tweet body + * @return the list + */ + List findTweetByBody(String tweetBody); + + /** + * Find tweet by device. + * + * @param deviceName + * the device name + * @return the list + */ + List findTweetByDevice(String deviceName); + + /** + * Close. + */ + void close(); + + void createEntityManager(); + + void closeEntityManager(); + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/TwitterService.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/TwitterService.java new file mode 100644 index 000000000..0f3ce9001 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/dao/TwitterService.java @@ -0,0 +1,228 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.dao; + +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Query; + +import com.impetus.client.twitter.entities.ExternalLinkMongo; +import com.impetus.client.twitter.entities.PreferenceMongo; +import com.impetus.client.twitter.entities.TweetMongo; +import com.impetus.client.twitter.entities.UserMongo; +import com.impetus.client.utils.MongoUtils; + +/** + * Data access object class for implementation of twitter. + * + * @author amresh.singh + */ +public class TwitterService extends SuperDao implements Twitter +{ + private EntityManager em; + + private EntityManagerFactory emf; + + private String pu; + + public TwitterService(String persistenceUnitName) + { + this.pu = persistenceUnitName; + if (emf == null) + { + try + { + emf = createEntityManagerFactory(persistenceUnitName); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + } + + @Override + public void createEntityManager() + { + if (em == null) + { + em = emf.createEntityManager(); + } + } + + @Override + public void closeEntityManager() + { + if (em != null) + { + em.close(); + em = null; + } + } + + @Override + public void close() + { + if (emf != null) + { + MongoUtils.dropDatabase(emf, pu); + emf.close(); + } + } + + @Override + public void addUser(UserMongo user) + { + em.persist(user); + } + + @Override + public void addUser(String userId, String name, String password, String relationshipStatus) + { + UserMongo user = new UserMongo(userId, name, password, relationshipStatus); + em.persist(user); + + } + + @Override + public void savePreference(String userId, PreferenceMongo preference) + { + + UserMongo user = em.find(UserMongo.class, userId); + user.setPreference(preference); + em.persist(user); + } + + @Override + public void addExternalLink(String userId, String linkId, String linkType, String linkAddress) + { + UserMongo user = em.find(UserMongo.class, userId); + user.addExternalLink(new ExternalLinkMongo(linkId, linkType, linkAddress)); + + em.persist(user); + } + + @Override + public void addTweet(String userId, String tweetBody, String device) + { + UserMongo user = em.find(UserMongo.class, userId); + user.addTweet(new TweetMongo(tweetBody, device)); + em.persist(user); + } + + @Override + public void startFollowing(String userId, String friendUserId) + { + UserMongo user = em.find(UserMongo.class, userId); + UserMongo friend = em.find(UserMongo.class, friendUserId); + + user.addFriend(friend); + em.persist(user); + + friend.addFollower(user); + em.persist(friend); + } + + @Override + public void addFollower(String userId, String followerUserId) + { + UserMongo user = em.find(UserMongo.class, userId); + UserMongo follower = em.find(UserMongo.class, followerUserId); + + user.addFollower(follower); + em.persist(user); + } + + @Override + public UserMongo findUserById(String userId) + { + UserMongo user = em.find(UserMongo.class, userId); + return user; + } + + @Override + public void removeUser(UserMongo user) + { + em.remove(user); + } + + @Override + public void mergeUser(UserMongo user) + { + em.merge(user); + } + + @Override + public List getAllUsers() + { + + Query q = em.createQuery("select u from UserMongo u"); + + List users = q.getResultList(); + + return users; + } + + @Override + public List getAllTweets(String userId) + { + Query q = em.createQuery("select u from UserMongo u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + else + { + return users.get(0).getTweets(); + } + } + + @Override + public List getFollowers(String userId) + { + Query q = em.createQuery("select u from UserMongo u where u.userId =:userId"); + q.setParameter("userId", userId); + List users = q.getResultList(); + if (users == null || users.isEmpty()) + { + return null; + } + return users.get(0).getFollowers(); + } + + @Override + public List findTweetByBody(String tweetBody) + { + Query q = em.createQuery("select u.tweet_body from UserMongo u where u.tweet_body like :body"); + q.setParameter("body", tweetBody); + List tweets = q.getResultList(); + return tweets; + } + + @Override + public List findTweetByDevice(String deviceName) + { + Query q = em.createQuery("select u.tweeted_from from UserMongo u where u.tweeted_from like :device"); + q.setParameter("device", deviceName); + List tweets = q.getResultList(); + return tweets; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/ExternalLinkMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/ExternalLinkMongo.java new file mode 100644 index 000000000..fbfc283c7 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/ExternalLinkMongo.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for user's External link details + * + * @author amresh.singh + */ + +@Entity +@Table(name = "EXTERNAL_LINK", schema = "KunderaExamples@mongoTest") +public class ExternalLinkMongo +{ + + @Id + @Column(name = "EXT_LINK_ID") + private String extLinkId; + + @Column(name = "LINK_TYPE") + private String linkType; + + @Column(name = "LINK_ADDRESS") + private String linkAddress; + + public ExternalLinkMongo() + { + } + + public ExternalLinkMongo(String extLinkId, String type, String address) + { + this.extLinkId = extLinkId; + this.linkType = type; + this.linkAddress = address; + } + + /** + * @return the extLinkId + */ + public String getExtLinkId() + { + return extLinkId; + } + + /** + * @param extLinkId + * the extLinkId to set + */ + public void setExtLinkId(String extLinkId) + { + this.extLinkId = extLinkId; + } + + /** + * @return the linkType + */ + public String getLinkType() + { + return linkType; + } + + /** + * @param linkType + * the linkType to set + */ + public void setLinkType(String linkType) + { + this.linkType = linkType; + } + + /** + * @return the linkAddress + */ + public String getLinkAddress() + { + return linkAddress; + } + + /** + * @param linkAddress + * the linkAddress to set + */ + public void setLinkAddress(String linkAddress) + { + this.linkAddress = linkAddress; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PersonalDetailMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PersonalDetailMongo.java new file mode 100644 index 000000000..4f94360f4 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PersonalDetailMongo.java @@ -0,0 +1,125 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsMongo; + +/** + * Entity class for user's personal details + * + * @author amresh.singh + */ + +@Embeddable +public class PersonalDetailMongo +{ + @Column(name = "personal_detail_id") + private String personalDetailId; + + @Column(name = "name") + private String name; + + @Column(name = "password") + private String password; + + @Column(name = "rel_status") + private String relationshipStatus; + + public PersonalDetailMongo() + { + + } + + public PersonalDetailMongo(String name, String password, String relationshipStatus) + { + setPersonalDetailId(ExampleUtilsMongo.getUniqueId()); + setName(name); + setPassword(password); + setRelationshipStatus(relationshipStatus); + } + + /** + * @return the personalDetailId + */ + public String getPersonalDetailId() + { + return personalDetailId; + } + + /** + * @param personalDetailId + * the personalDetailId to set + */ + public void setPersonalDetailId(String personalDetailId) + { + this.personalDetailId = personalDetailId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the password + */ + public String getPassword() + { + return password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) + { + this.password = password; + } + + /** + * @return the relationshipStatus + */ + public String getRelationshipStatus() + { + return relationshipStatus; + } + + /** + * @param relationshipStatus + * the relationshipStatus to set + */ + public void setRelationshipStatus(String relationshipStatus) + { + this.relationshipStatus = relationshipStatus; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PreferenceMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PreferenceMongo.java new file mode 100644 index 000000000..a3ea66f71 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/PreferenceMongo.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * Entity class for User Preferences + * + * @author amresh.singh + */ + +@Entity +@Table(name = "PREFERENCE", schema = "KunderaExamples@mongoTest") +public class PreferenceMongo +{ + @Id + @Column(name = "PREFERENCE_ID") + String preferenceId; + + @Column(name = "WEBSITE_THEME") + String websiteTheme; + + @Column(name = "PRIVACY_LEVEL") + String privacyLevel; // 1, 2, 3 + + public PreferenceMongo() + { + + } + + public PreferenceMongo(String preferenceId, String theme, String privacyLevel) + { + this.preferenceId = preferenceId; + this.websiteTheme = theme; + this.privacyLevel = privacyLevel; + } + + /** + * @return the preferenceId + */ + public String getPreferenceId() + { + return preferenceId; + } + + /** + * @param preferenceId + * the preferenceId to set + */ + public void setPreferenceId(String preferenceId) + { + this.preferenceId = preferenceId; + } + + /** + * @return the websiteTheme + */ + public String getWebsiteTheme() + { + return websiteTheme; + } + + /** + * @param websiteTheme + * the websiteTheme to set + */ + public void setWebsiteTheme(String websiteTheme) + { + this.websiteTheme = websiteTheme; + } + + /** + * @return the privacyLevel + */ + public String getPrivacyLevel() + { + return privacyLevel; + } + + /** + * @param privacyLevel + * the privacyLevel to set + */ + public void setPrivacyLevel(String privacyLevel) + { + this.privacyLevel = privacyLevel; + } +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/RoleMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/RoleMongo.java new file mode 100644 index 000000000..c38e96f26 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/RoleMongo.java @@ -0,0 +1,88 @@ +package com.impetus.client.twitter.entities; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ +@Entity +@Table(name = "Rol", schema = "KunderaExamples@mongoTest") +public class RoleMongo +{ + + @Id + @Column + private Integer rolId; + + @Column + private String name; + + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "userRol") + private List segUsuarioList; + + public RoleMongo() + { + + } + + /** + * @return the rolId + */ + public Integer getRolId() + { + return rolId; + } + + /** + * @param rolId + * the rolId to set + */ + public void setRolId(Integer rolId) + { + this.rolId = rolId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the segUsuarioList + */ + public List getSegUsuarioList() + { + return segUsuarioList; + } + + /** + * @param segUsuarioList + * the segUsuarioList to set + */ + public void setSegUsuarioList(List segUsuarioList) + { + this.segUsuarioList = segUsuarioList; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/TweetMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/TweetMongo.java new file mode 100644 index 000000000..2256bb026 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/TweetMongo.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +import com.impetus.client.twitter.utils.ExampleUtilsMongo; + +/** + * Class for Tweets + * + * @author amresh.singh + */ + +@Embeddable +public class TweetMongo +{ + + @Column(name = "tweet_id") + private String tweetId; + + @Column(name = "tweet_body") + private String body; + + @Column(name = "tweeted_from") + private String device; + + // private long timestamp; + + public TweetMongo(String body, String device) + { + this.tweetId = ExampleUtilsMongo.getUniqueId(); + this.body = body; + this.device = device; + // this.timestamp = ExampleUtils.getCurrentTimestamp(); + } + + public TweetMongo() + { + + } + + /** + * @return the tweetId + */ + public String getTweetId() + { + return tweetId; + } + + /** + * @param tweetId + * the tweetId to set + */ + public void setTweetId(String tweetId) + { + this.tweetId = tweetId; + } + + /** + * @return the body + */ + public String getBody() + { + return body; + } + + /** + * @param body + * the body to set + */ + public void setBody(String body) + { + this.body = body; + } + + /** + * @return the device + */ + public String getDevice() + { + return device; + } + + /** + * @param device + * the device to set + */ + public void setDevice(String device) + { + this.device = device; + } + + /* *//** + * @return the timestamp + */ + /* + * public long getTimestamp() { return timestamp; } + *//** + * @param timestamp + * the timestamp to set + */ + /* + * public void setTimestamp(long timestamp) { this.timestamp = timestamp; } + */ +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/User.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/User.java new file mode 100644 index 000000000..00a539994 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/User.java @@ -0,0 +1,148 @@ +package com.impetus.client.twitter.entities; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * @author vivek.mishra + * + */ +@Entity +@Table(name = "User", schema = "KunderaExamples@mongoTest") +public class User +{ + @Id + @Column + private Integer userId; + + @Column + private String name; + + @Column + private String email; + + @Column + private Integer age; + + @Column + private String lastName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolId") + private RoleMongo userRol; + + /** + * + */ + public User() + { + } + + /** + * @return the userId + */ + public Integer getUserId() + { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(Integer userId) + { + this.userId = userId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the email + */ + public String getEmail() + { + return email; + } + + /** + * @param email + * the email to set + */ + public void setEmail(String email) + { + this.email = email; + } + + /** + * @return the age + */ + public Integer getAge() + { + return age; + } + + /** + * @param age + * the age to set + */ + public void setAge(Integer age) + { + this.age = age; + } + + /** + * @return the lastName + */ + public String getLastName() + { + return lastName; + } + + /** + * @param lastName + * the lastName to set + */ + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + /** + * @return the userRol + */ + public RoleMongo getUserRol() + { + return userRol; + } + + /** + * @param userRol + * the userRol to set + */ + public void setUserRol(RoleMongo userRol) + { + this.userRol = userRol; + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/UserMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/UserMongo.java new file mode 100644 index 000000000..ad403cf54 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/entities/UserMongo.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.entities; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +/** + * @author impetus + * + */ +@Entity +@Table(name = "USER", schema = "KunderaExamples@mongoTest") +public class UserMongo +{ + + @Id + @Column(name = "USER_ID") + private String userId; + + // Embedded object, will persist co-located + @Embedded + private PersonalDetailMongo personalDetail; + + // Element collection, will persist co-located + @ElementCollection + @CollectionTable(name = "tweeted") + private List tweets; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FRIEND_ID") + private List friends; // List of users whom I follow + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "FOLLOWER_ID") + private List followers; // List of users who are following me + + // One-to-one, will be persisted separately + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "PREFERENCE_ID") + private PreferenceMongo preference; + + // One to many, will be persisted separately + @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER) + @JoinColumn(name = "USER_ID") + private Set externalLinks; + + public UserMongo() + { + + } + + public UserMongo(String userId, String name, String password, String relationshipStatus) + { + PersonalDetailMongo pd = new PersonalDetailMongo(name, password, relationshipStatus); + setUserId(userId); + setPersonalDetail(pd); + } + + /** + * @return the userId + */ + public String getUserId() + { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(String userId) + { + this.userId = userId; + } + + /** + * @return the personalDetail + */ + public PersonalDetailMongo getPersonalDetail() + { + return personalDetail; + } + + /** + * @param personalDetail + * the personalDetail to set + */ + public void setPersonalDetail(PersonalDetailMongo personalDetail) + { + this.personalDetail = personalDetail; + } + + /** + * @return the tweets + */ + public List getTweets() + { + return tweets; + } + + /** + * @param tweets + * the tweets to set + */ + public void addTweet(TweetMongo tweet) + { + if (this.tweets == null || this.tweets.isEmpty()) + { + this.tweets = new ArrayList(); + } + this.tweets.add(tweet); + } + + /** + * @return the preference + */ + public PreferenceMongo getPreference() + { + return preference; + } + + /** + * @param preference + * the preference to set + */ + public void setPreference(PreferenceMongo preference) + { + this.preference = preference; + } + + /** + * @return the externalLinks + */ + public Set getExternalLinks() + { + return externalLinks; + } + + /** + * @param imDetails + * the imDetails to set + */ + public void addExternalLink(ExternalLinkMongo externalLink) + { + if (this.externalLinks == null || this.externalLinks.isEmpty()) + { + this.externalLinks = new HashSet(); + } + + this.externalLinks.add(externalLink); + } + + /** + * @return the friends + */ + public List getFriends() + { + return friends; + } + + /** + * @param friends + * the friends to set + */ + public void addFriend(UserMongo friend) + { + if (this.friends == null || this.friends.isEmpty()) + { + this.friends = new ArrayList(); + } + this.friends.add(friend); + } + + /** + * @return the followers + */ + public List getFollowers() + { + return followers; + } + + /** + * @param followers + * the followers to set + */ + public void addFollower(UserMongo follower) + { + if (this.followers == null || this.followers.isEmpty()) + { + this.followers = new ArrayList(); + } + + this.followers.add(follower); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsMongo.java b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsMongo.java new file mode 100644 index 000000000..6f843b9cd --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/twitter/utils/ExampleUtilsMongo.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.twitter.utils; + +import java.util.Date; +import java.util.UUID; + +/** + * Class for utility methods + * + * @author amresh.singh + */ +public class ExampleUtilsMongo +{ + public static String getUniqueId() + { + return UUID.randomUUID().toString(); + } + + public static long getCurrentTimestamp() + { + return new Date().getTime(); + } + +} diff --git a/src/kundera-mongo/src/test/java/com/impetus/client/utils/MongoUtils.java b/src/kundera-mongo/src/test/java/com/impetus/client/utils/MongoUtils.java new file mode 100644 index 000000000..108f35666 --- /dev/null +++ b/src/kundera-mongo/src/test/java/com/impetus/client/utils/MongoUtils.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.utils; + +import java.lang.reflect.Field; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.mongodb.MongoDBClient; +import com.impetus.kundera.client.Client; +import com.mongodb.DB; + +/** + * @author Kuldeep Mishra + * + */ +public class MongoUtils +{ + + private static final Logger logger = LoggerFactory.getLogger(MongoUtils.class); + + /** + * + */ + public static void dropDatabase(EntityManagerFactory emf, String pu) + { + EntityManager em = null; + Map clients = null; + MongoDBClient client = null; + if (emf != null) + em = emf.createEntityManager(); + + if (em != null) + clients = (Map) em.getDelegate(); + if (clients != null) + client = (MongoDBClient) clients.get(pu); + if (client != null) + { + try + { + Field db = client.getClass().getDeclaredField("mongoDb"); + if (!db.isAccessible()) + { + db.setAccessible(true); + } + DB mongoDB = (DB) db.get(client); + mongoDB.dropDatabase(); + } + catch (SecurityException e) + { + logger.error("Error while truncating db",e); + } + + catch (NoSuchFieldException e) + { + logger.error("Error while truncating db",e); + } + catch (IllegalArgumentException e) + { + logger.error("Error while truncating db",e); + } + catch (IllegalAccessException e) + { + logger.error("Error while truncating db",e); + } + } + + } +} diff --git a/src/kundera-mongo/src/test/resources/META-INF/persistence.xml b/src/kundera-mongo/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..355bf6f38 --- /dev/null +++ b/src/kundera-mongo/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,120 @@ + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + diff --git a/src/kundera-mongo/src/test/resources/META-INF/persistence_2_0.xsd b/src/kundera-mongo/src/test/resources/META-INF/persistence_2_0.xsd new file mode 100644 index 000000000..d94620392 --- /dev/null +++ b/src/kundera-mongo/src/test/resources/META-INF/persistence_2_0.xsd @@ -0,0 +1,354 @@ + + + + + + + @(#)persistence_2_0.xsd 1.0 October 1 2009 + + + + + + + Copyright (c) 2008, 2009 Sun Microsystems. All rights reserved. + + This program and the accompanying materials are made available under the + terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 + which accompanies this distribution. + The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html + and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + + Contributors: + Linda DeMichiel - Java Persistence 2.0, Version 2.0 (October 1, 2009) + Specification available from http://jcp.org/en/jsr/detail?id=317 + + + + + + + ... + + + ]]> + + + + + + + + + + + + + + + + + + + + + + Configuration of a persistence unit. + + + + + + + + + + + + Description of this persistence unit. + + + + + + + + + + + + Provider class that supplies EntityManagers for this + persistence unit. + + + + + + + + + + + + The container-specific name of the JTA datasource to use. + + + + + + + + + + + + The container-specific name of a non-JTA datasource to use. + + + + + + + + + + + + File containing mapping information. Loaded as a resource + by the persistence provider. + + + + + + + + + + + + Jar file that is to be scanned for managed classes. + + + + + + + + + + + + Managed class to be included in the persistence unit and + to scan for annotations. It should be annotated + with either @Entity, @Embeddable or @MappedSuperclass. + + + + + + + + + + + + When set to true then only listed classes and jars will + be scanned for persistent classes, otherwise the + enclosing jar or directory will also be scanned. + Not applicable to Java SE persistence units. + + + + + + + + + + + + Defines whether caching is enabled for the + persistence unit if caching is supported by the + persistence provider. When set to ALL, all entities + will be cached. When set to NONE, no entities will + be cached. When set to ENABLE_SELECTIVE, only entities + specified as cacheable will be cached. When set to + DISABLE_SELECTIVE, entities specified as not cacheable + will not be cached. When not specified or when set to + UNSPECIFIED, provider defaults may apply. + + + + + + + + + + + + The validation mode to be used for the persistence unit. + + + + + + + + + + + + + A list of standard and vendor-specific properties + and hints. + + + + + + + + + A name-value pair. + + + + + + + + + + + + + + + + + + + + Name used in code to reference this persistence unit. + + + + + + + + + + + + Type of transactions used by EntityManagers from this + persistence unit. + + + + + + + + + + + + + + + + + + + public enum PersistenceUnitTransactionType {JTA, RESOURCE_LOCAL}; + + + + + + + + + + + + + + + + public enum SharedCacheMode { ALL, NONE, ENABLE_SELECTIVE, DISABLE_SELECTIVE, UNSPECIFIED}; + + + + + + + + + + + + + + + + + + + public enum ValidationMode { AUTO, CALLBACK, NONE}; + + + + + + + + + + + diff --git a/src/kundera-mongo/src/test/resources/kundera-mongo.properties b/src/kundera-mongo/src/test/resources/kundera-mongo.properties new file mode 100644 index 000000000..d6a74bf21 --- /dev/null +++ b/src/kundera-mongo/src/test/resources/kundera-mongo.properties @@ -0,0 +1,3 @@ +mongodb.servers=192.168.145.67:27017,192.168.145.118:27017,192.168.145.54:27017 +read.preference=primary +socket.timeout=1000000 \ No newline at end of file diff --git a/src/kundera-mongo/src/test/resources/kunderaMongoTest.xml b/src/kundera-mongo/src/test/resources/kunderaMongoTest.xml new file mode 100644 index 000000000..2f11240c7 --- /dev/null +++ b/src/kundera-mongo/src/test/resources/kunderaMongoTest.xml @@ -0,0 +1,29 @@ + + + + + mongo + + + + + + + + + KunderaMongoSchemaGeneration + +
+ MongoDBCappedEntity + + + + + +
+ + + + + + \ No newline at end of file diff --git a/src/kundera-mongo/src/test/resources/log4j.properties b/src/kundera-mongo/src/test/resources/log4j.properties new file mode 100644 index 000000000..1b6227aaa --- /dev/null +++ b/src/kundera-mongo/src/test/resources/log4j.properties @@ -0,0 +1,15 @@ +log4j.rootLogger=WARN, DRFA, CONSOLE + +### direct log messages to stdout ### +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.File=${user.home}/kundera.log +# Rollover at midnight +log4j.appender.DRFA.DatePattern=.yyyy-MM-dd +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +# Pattern format: Date LogLevel LoggerName LogMessage +log4j.appender.DRFA.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n + + +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%d [%-5p] [%t] %c %x - %m%n diff --git a/src/kundera-neo4j/pom.xml b/src/kundera-neo4j/pom.xml new file mode 100644 index 000000000..812b6d836 --- /dev/null +++ b/src/kundera-neo4j/pom.xml @@ -0,0 +1,118 @@ + + 4.0.0 + + com.impetus + kundera + 2.7-SNAPSHOT + + com.impetus.client + kundera-neo4j + jar + kundera-neo4j + http://maven.apache.org + + + neo4j-release-repository + Neo4j Maven 2 release repository + http://m2.neo4j.org/releases + + true + + + false + + + + neo4j-snapshot-repository + Neo4j Maven 2 snapshot repository + http://m2.neo4j.org/snapshots + + true + + + false + + + + + + junit + junit + 4.8.2 + test + + + + + com.impetus.core + kundera-core + ${project.version} + + + + + org.neo4j + neo4j + 1.8.1 + + + + com.sun.jersey + jersey-client + 1.12 + + + + + + maven-compiler-plugin + + 1.6 + 1.6 + + + + + maven-assembly-plugin + 2.2.1 + + + jar-with-dependencies + + + + + org.apache.maven.plugins + maven-jar-plugin + 2.2 + + + + test-jar + + + + + + + diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/GraphEntityMapper.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/GraphEntityMapper.java new file mode 100644 index 000000000..efafb08b1 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/GraphEntityMapper.java @@ -0,0 +1,737 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.StringTokenizer; + +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.NotFoundException; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.index.Index; +import org.neo4j.graphdb.index.IndexHits; +import org.neo4j.graphdb.index.ReadableIndex; +import org.neo4j.graphdb.index.UniqueFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.neo4j.index.Neo4JIndexManager; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReaderException; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * Responsible for converting Neo4J graph (nodes+relationships) into JPA + * entities and vice versa + * + * @author amresh.singh + */ +public final class GraphEntityMapper +{ + /** Separator between constituents of composite key */ + private static final String COMPOSITE_KEY_SEPARATOR = "$CKS$"; + + private static final String PROXY_NODE_TYPE_KEY = "$NODE_TYPE$"; + + private static final String PROXY_NODE_VALUE = "$PROXY_NODE$"; + + /** The log. */ + private static Logger log = LoggerFactory.getLogger(GraphEntityMapper.class); + + private Neo4JIndexManager indexer; + + public GraphEntityMapper(Neo4JIndexManager indexer) + { + this.indexer = indexer; + } + + /** + * Fetches(and converts) {@link Node} instance from Entity object If it's a + * update operation, node is searched and attributes populated Otherwise + * Node is created into database (replacing any existing node) with + * attributes populated + * + * @param id + * TODO + */ + public Node getNodeFromEntity(Object entity, Object key, GraphDatabaseService graphDb, EntityMetadata m, + boolean isUpdate) + { + + // Construct top level node first, making sure unique ID in the index + Node node = null; + if (!isUpdate) + { + node = getOrCreateNodeWithUniqueFactory(entity, key, m, graphDb); + } + else + { + + node = searchNode(key, m, graphDb, true); + } + + if (node != null) + { + populateNodeProperties(entity, m, node); + } + + return node; + } + + /** + * Create "Proxy" nodes into Neo4J. Proxy nodes are defined as nodes in + * Neo4J that refer to a record in some other database. They cater to + * polyglot persistence cases. + */ + public Node createProxyNode(Object sourceNodeId, Object targetNodeId, GraphDatabaseService graphDb, + EntityMetadata sourceEntityMetadata, EntityMetadata targetEntityMetadata) + { + + String sourceNodeIdColumnName = ((AbstractAttribute) sourceEntityMetadata.getIdAttribute()).getJPAColumnName(); + String targetNodeIdColumnName = ((AbstractAttribute) targetEntityMetadata.getIdAttribute()).getJPAColumnName(); + + Node node = graphDb.createNode(); + node.setProperty(PROXY_NODE_TYPE_KEY, PROXY_NODE_VALUE); + node.setProperty(sourceNodeIdColumnName, sourceNodeId); + node.setProperty(targetNodeIdColumnName, targetNodeId); + return node; + } + + /** + * + * Converts a {@link Node} instance to entity object + */ + public Object getEntityFromNode(Node node, EntityMetadata m) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + // Iterate over, entity attributes + Set attributes = entityType.getSingularAttributes(); + + Object entity = null; + + try + { + entity = m.getEntityClazz().newInstance(); + + for (Attribute attribute : attributes) + { + Field field = (Field) attribute.getJavaMember(); + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + + // Set Entity level properties + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType()) + && m.getIdAttribute().getJavaType().equals(field.getType())) + { + Object idValue = deserializeIdAttributeValue(m, (String) node.getProperty(columnName)); + PropertyAccessorHelper.set(entity, field, idValue); + } + else if (!attribute.isCollection() && !attribute.isAssociation()) + { + + PropertyAccessorHelper.set(entity, field, fromNeo4JObject(node.getProperty(columnName), field)); + + } + } + } + catch (InstantiationException e) + { + log.error("Error while converting Neo4j object to entity, Caused by: ", e); + throw new EntityReaderException("Error while converting Neo4j object to entity", e); + } + catch (IllegalAccessException e) + { + log.error("Error while converting Neo4j object to entity, Caused by: ", e); + throw new EntityReaderException("Error while converting Neo4j object to entity", e); + } + catch (NotFoundException e) + { + log.info(e.getMessage()); + return null; + } + + return entity; + } + + /** + * + * Converts a {@link Relationship} object to corresponding entity object + */ + public Object getEntityFromRelationship(Relationship relationship, EntityMetadata topLevelEntityMetadata, + Relation relation) + { + EntityMetadata relationshipEntityMetadata = KunderaMetadataManager.getEntityMetadata(relation + .getMapKeyJoinClass()); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + relationshipEntityMetadata.getPersistenceUnit()); + EntityType entityType = metaModel.entity(relationshipEntityMetadata.getEntityClazz()); + + // Iterate over, entity attributes + Set attributes = entityType.getSingularAttributes(); + + Object entity = null; + + try + { + entity = relationshipEntityMetadata.getEntityClazz().newInstance(); + + for (Attribute attribute : attributes) + { + Field field = (Field) attribute.getJavaMember(); + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + + // Set Entity level properties + if (metaModel.isEmbeddable(relationshipEntityMetadata.getIdAttribute().getBindableJavaType()) + && relationshipEntityMetadata.getIdAttribute().getJavaType().equals(field.getType())) + { + Object idValue = deserializeIdAttributeValue(relationshipEntityMetadata, + (String) relationship.getProperty(columnName)); + PropertyAccessorHelper.set(entity, field, idValue); + } + else if (!attribute.isCollection() && !attribute.isAssociation() + && !field.getType().equals(topLevelEntityMetadata.getEntityClazz()) + && !field.getType().equals(relation.getTargetEntity())) + { + Object value = relationship.getProperty(columnName); + PropertyAccessorHelper.set(entity, field, fromNeo4JObject(value, field)); + + } + } + } + catch (InstantiationException e) + { + log.error("Error while converting Neo4j object to entity, Caused by: ", e); + throw new EntityReaderException("Error while converting Neo4j object to entity"); + } + catch (IllegalAccessException e) + { + log.error("Error while converting Neo4j object to entity, Caused by: ", e); + throw new EntityReaderException("Error while converting Neo4j object to entity"); + } + + return entity; + } + + /** + * Creates a Map containing all properties (and their values) for a given + * entity + * + * @param entity + * @param m + * @return + */ + public Map createNodeProperties(Object entity, EntityMetadata m) + { + Map props = new HashMap(); + + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + // Iterate over entity attributes + Set attributes = entityType.getSingularAttributes(); + for (Attribute attribute : attributes) + { + Field field = (Field) attribute.getJavaMember(); + + // Set Node level properties + if (!attribute.isCollection() && !attribute.isAssociation()) + { + + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + Object value = PropertyAccessorHelper.getObject(entity, field); + if (value != null) + { + props.put(columnName, toNeo4JProperty(value)); + } + } + } + return props; + } + + /** + * Populates Node properties from Entity object + * + * @param entity + * @param m + * @param node + */ + private void populateNodeProperties(Object entity, EntityMetadata m, Node node) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + EntityType entityType = metaModel.entity(m.getEntityClazz()); + + // Iterate over entity attributes + Set attributes = entityType.getSingularAttributes(); + for (Attribute attribute : attributes) + { + Field field = (Field) attribute.getJavaMember(); + + // Set Node level properties + if (!attribute.isCollection() && !attribute.isAssociation() && !((SingularAttribute) attribute).isId()) + { + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + Object value = PropertyAccessorHelper.getObject(entity, field); + if (value != null) + { + node.setProperty(columnName, toNeo4JProperty(value)); + } + } + } + } + + /** + * Populates a {@link Relationship} with attributes of a given relationship + * entity object relationshipObj + * + * @param entityMetadata + * @param targetNodeMetadata + * @param relationship + * @param relationshipObj + */ + public void populateRelationshipProperties(EntityMetadata entityMetadata, EntityMetadata targetNodeMetadata, + Relationship relationship, Object relationshipObj) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + EntityType entityType = metaModel.entity(relationshipObj.getClass()); + + Set attributes = entityType.getSingularAttributes(); + for (Attribute attribute : attributes) + { + Field f = (Field) attribute.getJavaMember(); + if (!f.getType().equals(entityMetadata.getEntityClazz()) + && !f.getType().equals(targetNodeMetadata.getEntityClazz())) + { + EntityMetadata relMetadata = KunderaMetadataManager.getEntityMetadata(relationshipObj.getClass()); + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + if (metaModel.isEmbeddable(relMetadata.getIdAttribute().getBindableJavaType()) + && ((SingularAttribute) attribute).isId()) + { + // Populate Embedded attribute value into relationship + Object id = PropertyAccessorHelper.getId(relationshipObj, relMetadata); + Object serializedIdValue = serializeIdAttributeValue(relMetadata, metaModel, id); + relationship.setProperty(columnName, serializedIdValue); + + // Populate attributes of embedded fields into relationship + Set embeddableAttributes = metaModel.embeddable( + relMetadata.getIdAttribute().getBindableJavaType()).getSingularAttributes(); + for (Attribute embeddableAttribute : embeddableAttributes) + { + String embeddedColumn = ((AbstractAttribute) embeddableAttribute).getJPAColumnName(); + if (embeddedColumn == null) + embeddedColumn = embeddableAttribute.getName(); + Object value = PropertyAccessorHelper + .getObject(id, (Field) embeddableAttribute.getJavaMember()); + + if (value != null) + relationship.setProperty(embeddedColumn, value); + } + } + else + { + Object value = PropertyAccessorHelper.getObject(relationshipObj, f); + relationship.setProperty(columnName, toNeo4JProperty(value)); + } + + } + } + + } + + /** + * Creates a Map containing all properties (and their values) for a given + * relationship entity + * + * @param entityMetadata + * @param targetEntityMetadata + * @param relationshipProperties + * @param relationshipEntity + */ + public Map createRelationshipProperties(EntityMetadata entityMetadata, + EntityMetadata targetEntityMetadata, Object relationshipEntity) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + EntityType entityType = metaModel.entity(relationshipEntity.getClass()); + Map relationshipProperties = new HashMap(); + + Set attributes = entityType.getSingularAttributes(); + for (Attribute attribute : attributes) + { + Field f = (Field) attribute.getJavaMember(); + if (!f.getType().equals(entityMetadata.getEntityClazz()) + && !f.getType().equals(targetEntityMetadata.getEntityClazz())) + { + String relPropertyName = ((AbstractAttribute) attribute).getJPAColumnName(); + Object value = PropertyAccessorHelper.getObject(relationshipEntity, f); + relationshipProperties.put(relPropertyName, toNeo4JProperty(value)); + } + } + return relationshipProperties; + } + + /** + * + * Gets (if available) or creates a node for the given entity + */ + private Node getOrCreateNodeWithUniqueFactory(final Object entity, final Object id, final EntityMetadata m, + GraphDatabaseService graphDb) + { + final String idColumnName = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + final MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + final String idUniqueValue = serializeIdAttributeValue(m, metaModel, id); + + UniqueFactory factory = new UniqueFactory.UniqueNodeFactory(graphDb, m.getIndexName()) + { + /** + * Initialize ID attribute + */ + @Override + protected void initialize(Node created, Map properties) + { + // Set Embeddable ID attribute + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + // Populate embedded field value in serialized format + created.setProperty(idColumnName, idUniqueValue); + + // Populated all other attributes of embedded into this node + Set embeddableAttributes = metaModel + .embeddable(m.getIdAttribute().getBindableJavaType()).getSingularAttributes(); + for (Attribute attribute : embeddableAttributes) + { + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + if (columnName == null) + columnName = attribute.getName(); + Object value = PropertyAccessorHelper.getObject(id, (Field) attribute.getJavaMember()); + + if (value != null) + created.setProperty(columnName, value); + } + } + else + { + created.setProperty(idColumnName, properties.get(idColumnName)); + } + + } + }; + + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + return factory.getOrCreate(idColumnName, idUniqueValue); + } + else + { + return factory.getOrCreate(idColumnName, id); + } + + } + + /** + * Prepares ID column value for embedded IDs by combining its attributes + * + * @param m + * @param id + * @param metaModel + * @return + */ + private String serializeIdAttributeValue(final EntityMetadata m, MetamodelImpl metaModel, Object id) + { + if (!metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + return null; + } + + Class embeddableClass = m.getIdAttribute().getBindableJavaType(); + String idUniqueValue = ""; + + for (Field embeddedField : embeddableClass.getDeclaredFields()) + { + if(!ReflectUtils.isTransientOrStatic(embeddedField)) + { + + Object value = PropertyAccessorHelper.getObject(id, embeddedField); + if (value != null && !StringUtils.isEmpty(value.toString())) + idUniqueValue = idUniqueValue + value + COMPOSITE_KEY_SEPARATOR; + } + } + + if (idUniqueValue.endsWith(COMPOSITE_KEY_SEPARATOR)) + idUniqueValue = idUniqueValue.substring(0, idUniqueValue.length() - COMPOSITE_KEY_SEPARATOR.length()); + return idUniqueValue; + } + + /** + * Prepares Embedded ID field from value prepared via + * serializeIdAttributeValue method. + */ + private Object deserializeIdAttributeValue(final EntityMetadata m, String idValue) + { + if (idValue == null) + { + return null; + } + Class embeddableClass = m.getIdAttribute().getBindableJavaType(); + Object embeddedObject = null; + try + { + embeddedObject = embeddableClass.newInstance(); + } + catch (InstantiationException e) + { + log.error("Error while instantiating " + embeddableClass + + ". Did you define no argument constructor? Details:" + e.getMessage()); + throw new IllegalArgumentException("Error while instantiating " + embeddableClass + + ". Did you define no argument constructor?", e); + } + catch (IllegalAccessException e) + { + log.error("Error while instantiating " + embeddableClass + ".? Details:" + e.getMessage()); + throw new IllegalArgumentException("Error while instantiating " + embeddableClass, e); + } + + List tokens = new ArrayList(); + StringTokenizer st = new StringTokenizer((String) idValue, COMPOSITE_KEY_SEPARATOR); + while (st.hasMoreTokens()) + { + tokens.add((String) st.nextElement()); + } + + int count = 0; + for (Field embeddedField : embeddableClass.getDeclaredFields()) + { + if (!ReflectUtils.isTransientOrStatic(embeddedField)) + { + if (count < tokens.size()) + { + String value = tokens.get(count++); + PropertyAccessorHelper.set(embeddedObject, embeddedField, value); + } + } + } + return embeddedObject; + } + + /** + * Gets (if available) or creates a relationship for the given entity + */ + private Relationship getOrCreateRelationshipWithUniqueFactory(Object entity, EntityMetadata m, + GraphDatabaseService graphDb) + { + Object id = PropertyAccessorHelper.getObject(entity, (Field) m.getIdAttribute().getJavaMember()); + final String idFieldName = m.getIdAttribute().getName(); + + UniqueFactory factory = new UniqueFactory.UniqueRelationshipFactory(graphDb, m.getIndexName()) + { + + @Override + protected Relationship create(Map paramMap) + { + return null; + } + + @Override + protected void initialize(Relationship relationship, Map properties) + { + relationship.setProperty(idFieldName, properties.get(idFieldName)); + } + }; + + return factory.getOrCreate(idFieldName, id); + } + + /** + * Converts a given field value to an object that is Neo4J compatible + * + * @param source + * @return + */ + public Object toNeo4JProperty(Object source) + { + if (source instanceof BigDecimal || source instanceof BigInteger) + { + return source.toString(); + } + else if ((source instanceof Calendar) || (source instanceof GregorianCalendar)) + { + return PropertyAccessorHelper.fromSourceToTargetClass(String.class, Date.class, + ((Calendar) source).getTime()); + } + if (source instanceof Date) + { + Class sourceClass = source.getClass(); + return PropertyAccessorHelper.fromSourceToTargetClass(String.class, sourceClass, source); + } + return source; + } + + /** + * Converts a property stored in Neo4J (nodes or relationship) to + * corresponding entity field value + */ + public Object fromNeo4JObject(Object source, Field field) + { + Class targetClass = field.getType(); + + if (targetClass.isAssignableFrom(BigDecimal.class) || targetClass.isAssignableFrom(BigInteger.class)) + { + return PropertyAccessorHelper.fromSourceToTargetClass(field.getType(), source.getClass(), source); + } + else if (targetClass.isAssignableFrom(Calendar.class) || targetClass.isAssignableFrom(GregorianCalendar.class)) + { + Date d = (Date) PropertyAccessorHelper.fromSourceToTargetClass(Date.class, source.getClass(), source); + Calendar cal = Calendar.getInstance(); + cal.setTime(d); + return cal; + } + else if (targetClass.isAssignableFrom(Date.class)) + { + return PropertyAccessorHelper.fromSourceToTargetClass(field.getType(), source.getClass(), source); + } + else + { + return source; + } + + } + + /** + * Searches a node from the database for a given key + */ + public Node searchNode(Object key, EntityMetadata m, GraphDatabaseService graphDb, boolean skipProxy) + { + Node node = null; + String idColumnName = ((AbstractAttribute) m.getIdAttribute()).getJPAColumnName(); + + final MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + m.getPersistenceUnit()); + if (metaModel.isEmbeddable(m.getIdAttribute().getBindableJavaType())) + { + key = serializeIdAttributeValue(m, metaModel, key); + } + + if (indexer.isNodeAutoIndexingEnabled(graphDb)) + { + // Get the Node auto index + ReadableIndex autoNodeIndex = graphDb.index().getNodeAutoIndexer().getAutoIndex(); + IndexHits nodesFound = autoNodeIndex.get(idColumnName, key); + node = getMatchingNodeFromIndexHits(nodesFound, skipProxy); + } + else + { + // Searching within manually created indexes + Index nodeIndex = graphDb.index().forNodes(m.getIndexName()); + IndexHits nodesFound = nodeIndex.get(idColumnName, key); + node = getMatchingNodeFromIndexHits(nodesFound, skipProxy); + } + + return node; + } + + /** + * Fetches first Non-proxy node from Index Hits + * + * @param skipProxy + * @param nodesFound + * @return + */ + protected Node getMatchingNodeFromIndexHits(IndexHits nodesFound, boolean skipProxy) + { + Node node = null; + try + { + if (nodesFound == null || nodesFound.size() == 0 || !nodesFound.hasNext()) + { + return null; + } + else + { + if (skipProxy) + node = getNonProxyNode(nodesFound); + else + node = nodesFound.next(); + } + } + finally + { + nodesFound.close(); + } + return node; + } + + /** + * Fetches Non-proxy nodes from index hits + */ + private Node getNonProxyNode(IndexHits nodesFound) + { + Node node = null; + if (nodesFound.hasNext()) + { + node = nodesFound.next(); + } + else + { + return null; + } + + try + { + Object proxyNodeProperty = node.getProperty(PROXY_NODE_TYPE_KEY); + } + catch (NotFoundException e) + { + return node; + } + catch (IllegalStateException e) + { + return node; + } + return getNonProxyNode(nodesFound); + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClient.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClient.java new file mode 100644 index 000000000..754e10c53 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClient.java @@ -0,0 +1,810 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.persistence.FetchType; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.neo4j.graphdb.Direction; +import org.neo4j.graphdb.DynamicRelationshipType; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.NotInTransactionException; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.index.Index; +import org.neo4j.graphdb.index.IndexHits; +import org.neo4j.graphdb.index.ReadableIndex; +import org.neo4j.unsafe.batchinsert.BatchInserter; +import org.neo4j.unsafe.batchinsert.BatchInserterIndexProvider; +import org.neo4j.unsafe.batchinsert.BatchInserters; +import org.neo4j.unsafe.batchinsert.LuceneBatchInserterIndexProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.neo4j.config.Neo4JPropertyReader; +import com.impetus.client.neo4j.config.Neo4JPropertyReader.Neo4JSchemaMetadata; +import com.impetus.client.neo4j.index.Neo4JIndexManager; +import com.impetus.client.neo4j.query.Neo4JQuery; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.db.RelationHolder; +import com.impetus.kundera.lifecycle.states.RemovedState; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.Relation; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.AssociationBuilder; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.KunderaTransactionException; +import com.impetus.kundera.persistence.TransactionBinder; +import com.impetus.kundera.persistence.TransactionResource; +import com.impetus.kundera.persistence.api.Batcher; +import com.impetus.kundera.persistence.context.jointable.JoinTableData; +import com.impetus.kundera.property.PropertyAccessorHelper; +import com.impetus.kundera.utils.ReflectUtils; + +/** + * Implementation of {@link Client} using Neo4J Native Java driver (see Embedded + * Java driver at http://www.neo4j.org/develop/drivers) + * + * @author amresh.singh + */ +public class Neo4JClient extends Neo4JClientBase implements Client, TransactionBinder, Batcher +{ + + private static Logger log = LoggerFactory.getLogger(Neo4JClient.class); + + /** + * Reference to Neo4J client factory. + */ + private Neo4JClientFactory factory; + + private EntityReader reader; + + private GraphEntityMapper mapper; + + private TransactionResource resource; + + private Neo4JIndexManager indexer; + + Neo4JClient(final Neo4JClientFactory factory, Map puProperties, String persistenceUnit) + { + this.persistenceUnit = persistenceUnit; + this.factory = factory; + reader = new Neo4JEntityReader(); + indexer = new Neo4JIndexManager(); + mapper = new GraphEntityMapper(indexer); + populateBatchSize(persistenceUnit, puProperties); + this.clientMetadata = factory.getClientMetadata(); + + } + + @Override + public void populateClientProperties(Client client, Map properties) + { + // All client properties currently are those that are specified in + // neo4j.properties (or custom XML configuration file according to + // Kundera format) + // No custom property currently defined by Kundera, leaving empty + if (log.isDebugEnabled()) + log.debug("No custom property to set for Neo4J"); + } + + /** + * Finds an entity from graph database + */ + @Override + public Object find(Class entityClass, Object key) + { + GraphDatabaseService graphDb = null; + if (resource != null) + { + graphDb = getConnection(); + } + + if (graphDb == null) + graphDb = factory.getConnection(); + + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entityClass); + + Object entity = null; + Node node = mapper.searchNode(key, m, graphDb, true); + + if (node != null && !((Neo4JTransaction) resource).containsNodeId(node.getId())) + + { + entity = getEntityWithAssociationFromNode(m, node); + } + + return entity; + } + + @Override + public List findAll(Class entityClass, String[] columnsToSelect, Object... keys) + { + List entities = new ArrayList(); + for (Object key : keys) + { + entities.add(find(entityClass, key)); + } + return entities; + } + + @Override + public List find(Class entityClass, Map embeddedColumnMap) + { + throw new UnsupportedOperationException("Embedded attributes not supported in Neo4J as of now"); + } + + @Override + public void close() + { + // Closure is internally handled by Neo4J + } + + /** + * Deletes an entity from database + */ + @Override + public void delete(Object entity, Object key) + { + // All Modifying Neo4J operations must be executed within a transaction + checkActiveTransaction(); + + GraphDatabaseService graphDb = getConnection(); + + // Find Node for this particular entity + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + Node node = mapper.searchNode(key, m, graphDb, true); + if (node != null) + { + // Remove this particular node, if not already deleted in current + // transaction + if (!((Neo4JTransaction) resource).containsNodeId(node.getId())) + { + node.delete(); + + // Manually remove node index if applicable + indexer.deleteNodeIndex(m, graphDb, node); + + // Remove all relationship edges attached to this node + // (otherwise an + // exception is thrown) + for (Relationship relationship : node.getRelationships()) + { + relationship.delete(); + + // Manually remove relationship index if applicable + indexer.deleteRelationshipIndex(m, graphDb, relationship); + } + + ((Neo4JTransaction) resource).addNodeId(node.getId()); + } + } + else + { + if (log.isDebugEnabled()) + log.debug("Entity to be deleted doesn't exist in graph. Doing nothing"); + } + } + + @Override + public void persistJoinTable(JoinTableData joinTableData) + { + throw new UnsupportedOperationException("Join Table not supported for Neo4J as of now"); + } + + @Override + public List getColumnsById(String schemaName, String tableName, String pKeyColumnName, String columnName, + Object pKeyColumnValue, Class columnJavaType) + { + throw new UnsupportedOperationException("Operation not supported for Neo4J"); + } + + @Override + public Object[] findIdsByColumn(String schemaName, String tableName, String pKeyName, String columnName, + Object columnValue, Class entityClazz) + { + throw new UnsupportedOperationException("Operation not supported for Neo4J"); + } + + @Override + public void deleteByColumn(String schemaName, String tableName, String columnName, Object columnValue) + { + throw new UnsupportedOperationException("Operation not supported for Neo4J"); + } + + @Override + public List findByRelation(String colName, Object colValue, Class entityClazz) + { + throw new UnsupportedOperationException("Operation not supported for Neo4J"); + } + + @Override + public EntityReader getReader() + { + return reader; + } + + @Override + public Class getQueryImplementor() + { + return Neo4JQuery.class; + } + + /** + * Writes an entity to database + */ + @Override + protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id, List rlHolders) + { + if (log.isDebugEnabled()) + log.debug("Persisting " + entity); + + // All Modifying Neo4J operations must be executed within a transaction + checkActiveTransaction(); + + GraphDatabaseService graphDb = getConnection(); + + try + { + + // Top level node + Node node = mapper.getNodeFromEntity(entity, id, graphDb, entityMetadata, isUpdate); + + if (node != null) + { + ((Neo4JTransaction) resource).addProcessedNode(id, node); + + if (!rlHolders.isEmpty()) + { + for (RelationHolder rh : rlHolders) + { + // Search Node (to be connected to ) in Neo4J graph + EntityMetadata targetNodeMetadata = KunderaMetadataManager.getEntityMetadata(rh + .getRelationValue().getClass()); + Object targetNodeKey = PropertyAccessorHelper.getId(rh.getRelationValue(), targetNodeMetadata); + // Node targetNode = mapper.searchNode(targetNodeKey, + // targetNodeMetadata, graphDb); + + Node targetNode = null; // Target node connected through + // relationship + + /** + * If Relationship is with an entity in Neo4J, Target + * node must already have been created Get a handle of + * it from processed nodes and add edges to it. Else, if + * relationship is with an entity in a database other + * than Neo4J, create a "Proxy Node" that points to a + * row in other database. This proxy node contains key + * equal to primary key of row in other database. + * */ + + if (isEntityForNeo4J(targetNodeMetadata)) + { + targetNode = ((Neo4JTransaction) resource).getProcessedNode(targetNodeKey); + } + else + { + // Create Proxy nodes for insert requests + if (!isUpdate) + { + targetNode = mapper.createProxyNode(id, targetNodeKey, graphDb, entityMetadata, + targetNodeMetadata); + } + } + + if (targetNode != null) + { + // Join this node (source node) to target node via + // relationship + DynamicRelationshipType relType = DynamicRelationshipType.withName(rh.getRelationName()); + Relationship relationship = node.createRelationshipTo(targetNode, relType); + + // Populate relationship's own properties into it + Object relationshipObj = rh.getRelationVia(); + if (relationshipObj != null) + { + mapper.populateRelationshipProperties(entityMetadata, targetNodeMetadata, relationship, + relationshipObj); + + // After relationship creation, manually index + // it if desired + EntityMetadata relationMetadata = KunderaMetadataManager + .getEntityMetadata(relationshipObj.getClass()); + if (!isUpdate) + { + indexer.indexRelationship(relationMetadata, graphDb, relationship); + } + else + { + indexer.updateRelationshipIndex(relationMetadata, graphDb, relationship); + } + + } + } + + } + } + + // After node creation, manually index this node, if desired + if (!isUpdate) + { + indexer.indexNode(entityMetadata, graphDb, node); + } + else + { + indexer.updateNodeIndex(entityMetadata, graphDb, node); + } + } + + } + catch (Exception e) + { + log.error("Error while persisting entity " + entity + ", Caused by: ", e); + throw new PersistenceException(e); + } + } + + @Override + public void addBatch(com.impetus.kundera.graph.Node node) + { + if (node != null) + { + nodes.add(node); + } + if (batchSize > 0 && batchSize == nodes.size()) + { + executeBatch(); + nodes.clear(); + } + } + + @Override + public int executeBatch() + { + if (batchSize > 0) + { + boolean nodeAutoIndexingEnabled = indexer.isNodeAutoIndexingEnabled(factory.getConnection()); + boolean relationshipAutoIndexingEnabled = indexer + .isRelationshipAutoIndexingEnabled(factory.getConnection()); + + BatchInserter inserter = getBatchInserter(); + BatchInserterIndexProvider indexProvider = new LuceneBatchInserterIndexProvider(inserter); + + if (inserter == null) + { + log.error("Unable to create instance of BatchInserter. Opertion will fail"); + throw new PersistenceException("Unable to create instance of BatchInserter. Opertion will fail"); + } + + if (resource != null && resource.isActive()) + { + log.error("Batch Insertion MUST not be executed in a transaction"); + throw new PersistenceException("Batch Insertion MUST not be executed in a transaction"); + } + + Map pkToNodeIdMap = new HashMap(); + for (com.impetus.kundera.graph.Node graphNode : nodes) + { + if (graphNode.isDirty()) + { + graphNode.handlePreEvent(); + // Delete can not be executed in batch, deleting normally + if (graphNode.isInState(RemovedState.class)) + { + delete(graphNode.getData(), graphNode.getEntityId()); + } + else if (graphNode.isUpdate()) + { + // Neo4J allows only batch insertion, follow usual path + // for normal updates + persist(graphNode); + } + else + { + // Insert node + Object entity = graphNode.getData(); + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(entity.getClass()); + Object pk = PropertyAccessorHelper.getId(entity, m); + Map nodeProperties = mapper.createNodeProperties(entity, m); + long nodeId = inserter.createNode(nodeProperties); + pkToNodeIdMap.put(pk, nodeId); + + // Index Node + indexer.indexNodeUsingBatchIndexer(indexProvider, m, nodeId, nodeProperties, + nodeAutoIndexingEnabled); + + // Insert relationships for this particular node + if (!getRelationHolders(graphNode).isEmpty()) + { + for (RelationHolder rh : getRelationHolders(graphNode)) + { + // Search Node (to be connected to ) in Neo4J + // graph + EntityMetadata targetNodeMetadata = KunderaMetadataManager.getEntityMetadata(rh + .getRelationValue().getClass()); + Object targetNodeKey = PropertyAccessorHelper.getId(rh.getRelationValue(), + targetNodeMetadata); + Long targetNodeId = pkToNodeIdMap.get(targetNodeKey); + + if (targetNodeId != null) + { + /** + * Join this node (source node) to target + * node via relationship + */ + // Relationship Type + DynamicRelationshipType relType = DynamicRelationshipType.withName(rh + .getRelationName()); + + // Relationship Properties + Map relationshipProperties = null; + Object relationshipObj = rh.getRelationVia(); + if (relationshipObj != null) + { + EntityMetadata relationMetadata = KunderaMetadataManager + .getEntityMetadata(relationshipObj.getClass()); + + relationshipProperties = mapper.createRelationshipProperties(m, + targetNodeMetadata, relationshipObj); + + // Finally insert relationship + long relationshipId = inserter.createRelationship(nodeId, targetNodeId, + relType, relationshipProperties); + + // Index this relationship + indexer.indexRelationshipUsingBatchIndexer(indexProvider, relationMetadata, + relationshipId, relationshipProperties, relationshipAutoIndexingEnabled); + } + + } + } + } + } + graphNode.handlePostEvent(); + } + } + + // Shutdown Batch inserter + indexProvider.shutdown(); + inserter.shutdown(); + + // Restore Graph Database service + factory.setConnection((GraphDatabaseService) factory.createPoolOrConnection()); + + return pkToNodeIdMap.size(); + } + else + { + return 0; + } + + } + + /** + * Populates relationship entities into original entity + * + * @param m + * @param entity + * @param relationMap + * @param node + */ + private void populateRelations(EntityMetadata m, Object entity, Map relationMap, Node node, + Map nodeIdToEntityMap) + { + // Populate all relationship entities that are in Neo4J + for (Relation relation : m.getRelations()) + { + Class targetEntityClass = relation.getTargetEntity(); + EntityMetadata targetEntityMetadata = KunderaMetadataManager.getEntityMetadata(targetEntityClass); + Field property = relation.getProperty(); + if (relation.getPropertyType().isAssignableFrom(Map.class)) + { + Map targetEntitiesMap = new HashMap(); + + // If relationship entity is stored into Neo4J, fetch it + // immediately + if (isEntityForNeo4J(targetEntityMetadata)) + { + + for (Relationship relationship : node.getRelationships(Direction.OUTGOING, + DynamicRelationshipType.withName(relation.getJoinColumnName()))) + { + if (relationship == null) + { + continue; + } + + // Target Entity + Node endNode = relationship.getEndNode(); + if (endNode == null) + { + continue; + } + Object targetEntity = nodeIdToEntityMap.get(endNode.getId()); + if (targetEntity == null) + { + targetEntity = mapper.getEntityFromNode(endNode, targetEntityMetadata); + } + + // Relationship Entity + Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation); + + // If this relationship is bidirectional, put source + // entity into Map field for target entity + Field bidirectionalField = relation.getBiDirectionalField(); + Map sourceEntitiesMap = new HashMap(); + if (bidirectionalField != null) + { + for (Relationship incomingRelationship : endNode.getRelationships(Direction.INCOMING, + DynamicRelationshipType.withName(relation.getJoinColumnName()))) + { + Node startNode = incomingRelationship.getStartNode(); + Object sourceEntity = nodeIdToEntityMap.get(startNode.getId()); + if (sourceEntity == null) + { + sourceEntity = mapper.getEntityFromNode(startNode, m); + nodeIdToEntityMap.put(startNode.getId(), sourceEntity); + } + sourceEntitiesMap.put(relationshipEntity, sourceEntity); + } + PropertyAccessorHelper.set(targetEntity, bidirectionalField, sourceEntitiesMap); + } + + // Set references to Target and owning entity in + // relationship entity + Class relationshipClass = relation.getMapKeyJoinClass(); + for (Field f : relationshipClass.getDeclaredFields()) + { + if (!ReflectUtils.isTransientOrStatic(f)) + { + + if (f.getType().equals(m.getEntityClazz())) + { + PropertyAccessorHelper.set(relationshipEntity, f, entity); + } + else if (f.getType().equals(targetEntityClass)) + { + PropertyAccessorHelper.set(relationshipEntity, f, targetEntity); + } + } + } + targetEntitiesMap.put(relationshipEntity, targetEntity); + } + + PropertyAccessorHelper.set(entity, property, targetEntitiesMap); + } + + /** + * If relationship entity is stored in a database other than + * Neo4J foreign keys are stored in "Proxy Nodes", retrieve + * these foreign keys and set into EnhanceEntity + */ + else + { + + for (Relationship relationship : node.getRelationships(Direction.OUTGOING, + DynamicRelationshipType.withName(relation.getJoinColumnName()))) + { + Node proxyNode = relationship.getEndNode(); + + String targetEntityIdColumnName = ((AbstractAttribute) targetEntityMetadata.getIdAttribute()) + .getJPAColumnName(); + Object targetObjectId = proxyNode.getProperty(targetEntityIdColumnName); + Object relationshipEntity = mapper.getEntityFromRelationship(relationship, m, relation); + + targetEntitiesMap.put(targetObjectId, relationshipEntity); + } + + relationMap.put(relation.getJoinColumnName(), targetEntitiesMap); + } + } + } + } + + /** + * Returns instance of {@link BatchInserter} + */ + protected BatchInserter getBatchInserter() + { + PersistenceUnitMetadata puMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + Properties props = puMetadata.getProperties(); + + // Datastore file path + String datastoreFilePath = (String) props.get(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + if (StringUtils.isEmpty(datastoreFilePath)) + { + throw new PersistenceException( + "For Neo4J, it's mandatory to specify kundera.datastore.file.path property in persistence.xml"); + } + + // Shut down Graph DB, at a time only one service may have lock on DB + // file + if (factory.getConnection() != null) + { + factory.getConnection().shutdown(); + } + + BatchInserter inserter = null; + + // Create Batch inserter with configuration if specified + Neo4JSchemaMetadata nsmd = Neo4JPropertyReader.nsmd; + ClientProperties cp = nsmd != null ? nsmd.getClientProperties() : null; + if (cp != null) + { + DataStore dataStore = nsmd != null ? nsmd.getDataStore() : null; + Properties properties = dataStore != null && dataStore.getConnection() != null ? dataStore.getConnection() + .getProperties() : null; + + if (properties != null) + { + Map config = new HashMap((Map) properties); + inserter = BatchInserters.inserter(datastoreFilePath, config); + } + } + + // Create Batch inserter without configuration if not provided + if (inserter == null) + { + inserter = BatchInserters.inserter(datastoreFilePath); + } + return inserter; + } + + /** + * Binds Transaction resource to this client + */ + @Override + public void bind(TransactionResource resource) + { + if (resource != null && resource instanceof Neo4JTransaction) + { + ((Neo4JTransaction) resource).setGraphDb(factory.getConnection()); + this.resource = resource; + } + else + { + throw new KunderaTransactionException("Invalid transaction resource provided:" + resource + + " Should have been an instance of :" + Neo4JTransaction.class); + } + } + + public List executeLuceneQuery(EntityMetadata m, String luceneQuery) + { + log.info("Executing Lucene Query on Neo4J:" + luceneQuery); + + GraphDatabaseService graphDb = getConnection(); + List entities = new ArrayList(); + + if (!indexer.isNodeAutoIndexingEnabled(graphDb) && m.isIndexable()) + { + Index nodeIndex = graphDb.index().forNodes(m.getIndexName()); + + IndexHits hits = nodeIndex.query(luceneQuery); + addEntityFromIndexHits(m, entities, hits); + } + else + { + + ReadableIndex autoNodeIndex = graphDb.index().getNodeAutoIndexer().getAutoIndex(); + IndexHits hits = autoNodeIndex.query(luceneQuery); + addEntityFromIndexHits(m, entities, hits); + + } + return entities; + } + + /** + * @param m + * @param entities + * @param hits + */ + protected void addEntityFromIndexHits(EntityMetadata m, List entities, IndexHits hits) + { + for (Node node : hits) + { + if (node != null) + { + Object entity = getEntityWithAssociationFromNode(m, node); + if (entity != null) + { + + entities.add(entity); + + } + } + } + } + + /** + * @param m + * @param entities + * @param node + */ + private Object getEntityWithAssociationFromNode(EntityMetadata m, Node node) + { + Map relationMap = new HashMap(); + + /** + * Map containing Node ID as key and Entity object as value. Helps cache + * entity objects found earlier for faster lookup and prevents repeated + * processing + */ + Map nodeIdToEntityMap = new HashMap(); + + Object entity = mapper.getEntityFromNode(node, m); + + nodeIdToEntityMap.put(node.getId(), entity); + populateRelations(m, entity, relationMap, node, nodeIdToEntityMap); + + nodeIdToEntityMap.clear(); + + if (!relationMap.isEmpty() && entity != null) + { + return new EnhanceEntity(entity, PropertyAccessorHelper.getId(entity, m), relationMap); + } + else + { + return entity; + } + + } + + /** + * Checks whether there is an active transaction within this client Batch + * operations are run without any transaction boundary hence this check is + * not applicable for them All Modifying Neo4J operations must be executed + * within a transaction + */ + private void checkActiveTransaction() + { + if (batchSize == 0 && (resource == null || !resource.isActive())) + { + throw new NotInTransactionException("All Modifying Neo4J operations must be executed within a transaction"); + } + } + + public GraphDatabaseService getConnection() + { + if (resource != null) + { + return ((Neo4JTransaction) resource).getGraphDb(); + } + else + { + return factory.getConnection(); + } + + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientBase.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientBase.java new file mode 100644 index 000000000..829e281f7 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientBase.java @@ -0,0 +1,100 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.ClientBase; +import com.impetus.kundera.client.ClientPropertiesSetter; +import com.impetus.kundera.graph.Node; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Base class for all Neo4J clients + * + * @author amresh.singh + */ +public abstract class Neo4JClientBase extends ClientBase implements ClientPropertiesSetter +{ + private static Logger log = LoggerFactory.getLogger(Neo4JClientBase.class); + + /** Batch size. */ + protected int batchSize; + + /** list of nodes for batch processing. */ + protected List nodes = new ArrayList(); + + protected boolean isEntityForNeo4J(EntityMetadata entityMetadata) + { + String persistenceUnit = entityMetadata.getPersistenceUnit(); + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + String clientFactory = puMetadata.getProperty(PersistenceProperties.KUNDERA_CLIENT_FACTORY); + if (clientFactory.indexOf("com.impetus.client.neo4j") >= 0) + { + return true; + } + return false; + } + + /** + * @param persistenceUnit + * @param puProperties + */ + protected void populateBatchSize(String persistenceUnit, Map puProperties) + { + String batch_Size = puProperties != null ? (String) puProperties.get(PersistenceProperties.KUNDERA_BATCH_SIZE) + : null; + if (batch_Size != null) + { + batchSize = Integer.valueOf(batch_Size); + if (batchSize == 0) + { + throw new IllegalArgumentException("kundera.batch.size property must be numeric and > 0"); + } + } + else + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + batchSize = puMetadata.getBatchSize(); + } + } + + public int getBatchSize() + { + return batchSize; + } + + public void clear() + { + if (nodes != null) + { + nodes.clear(); + nodes = null; + nodes = new ArrayList(); + } + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientFactory.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientFactory.java new file mode 100644 index 000000000..0c2fb07ff --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JClientFactory.java @@ -0,0 +1,201 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang.StringUtils; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.factory.GraphDatabaseBuilder; +import org.neo4j.graphdb.factory.GraphDatabaseFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.client.neo4j.config.Neo4JPropertyReader; +import com.impetus.client.neo4j.config.Neo4JPropertyReader.Neo4JSchemaMetadata; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.PersistenceUnitConfigurationException; +import com.impetus.kundera.configure.schema.api.SchemaManager; +import com.impetus.kundera.loader.GenericClientFactory; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Factory of Neo4J client(s) + * + * @author amresh.singh + */ +public class Neo4JClientFactory extends GenericClientFactory +{ + + /** The logger. */ + private static Logger log = LoggerFactory.getLogger(Neo4JClientFactory.class); + + @Override + public void initialize(Map puProperties) + { + initializePropertyReader(); + setExternalProperties(puProperties); + } + + /** + * Create Neo4J Embedded Graph DB instance, that acts as a Neo4J connection + * repository for Neo4J If a Neo4j specfic client properties file is + * specified in persistence.xml, it initializes DB instance with those + * properties. Other DB instance is initialized with default properties. + */ + @Override + protected Object createPoolOrConnection() + { + if (log.isInfoEnabled()) + log.info("Initializing Neo4J database connection..."); + + PersistenceUnitMetadata puMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata() + .getPersistenceUnitMetadata(getPersistenceUnit()); + + Properties props = puMetadata.getProperties(); + String datastoreFilePath = (String) props.get(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + if (StringUtils.isEmpty(datastoreFilePath)) + { + throw new PersistenceUnitConfigurationException( + "For Neo4J, it's mandatory to specify kundera.datastore.file.path property in persistence.xml"); + } + + Neo4JSchemaMetadata nsmd = Neo4JPropertyReader.nsmd; + ClientProperties cp = nsmd != null ? nsmd.getClientProperties() : null; + + GraphDatabaseService graphDb = (GraphDatabaseService) getConnectionPoolOrConnection(); + + if (cp != null && graphDb == null) + { + DataStore dataStore = nsmd != null ? nsmd.getDataStore() : null; + + Properties properties = dataStore != null && dataStore.getConnection() != null ? dataStore.getConnection() + .getProperties() : null; + + if (properties != null) + { + Map config = new HashMap((Map) properties); + + GraphDatabaseBuilder builder = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(datastoreFilePath); + builder.setConfig(config); + + graphDb = builder.newGraphDatabase(); + // registerShutdownHook(graphDb); + } + } + + if (graphDb == null) + { + graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(datastoreFilePath); + // registerShutdownHook(graphDb); + } + + return graphDb; + } + + @Override + protected Client instantiateClient(String persistenceUnit) + { + return new Neo4JClient(this, externalProperties, persistenceUnit); + } + + @Override + public boolean isThreadSafe() + { + return true; + } + + @Override + public SchemaManager getSchemaManager(Map puProperties) + { + log.info("No schema manager implementation available (required) for Neo4J."); + return null; + } + + @Override + public void destroy() + { + this.externalProperties = null; + ((GraphDatabaseService) getConnectionPoolOrConnection()).shutdown(); + // Not required for multithreaded clients + } + + /** + * Retrieves {@link GraphDatabaseService} instance + * + * @return + */ + GraphDatabaseService getConnection() + { + return (GraphDatabaseService) getConnectionPoolOrConnection(); + } + + void setConnection(GraphDatabaseService graphDb) + { + setConnectionPoolOrConnection(graphDb); + } + + /** + * + */ + private void initializePropertyReader() + { + if (propertyReader == null) + { + propertyReader = new Neo4JPropertyReader(externalProperties); + propertyReader.read(getPersistenceUnit()); + } + } + + /** + * @param puProperties + */ + protected void setExternalProperties(Map puProperties) + { + if (this.externalProperties == null) + { + this.externalProperties = puProperties; + } + } + + /** + * Registers a shutdown hook for the Neo4j instance so that it shuts down + * nicely when the VM exits (even if you "Ctrl-C" the running example before + * it's completed) The EmbeddedGraphDatabase instance can be shared among + * multiple threads. Note however that you can’t create multiple instances + * pointing to the same database. + * + * @param graphDb + */ + /* + * private static void registerShutdownHook(final GraphDatabaseService + * graphDb) { Runtime.getRuntime().addShutdownHook(new Thread() { + * + * @Override public void run() { graphDb.shutdown(); } }); } + */ + @Override + protected void initializeLoadBalancer(String loadBalancingPolicyName) + { + throw new UnsupportedOperationException("Load balancing feature is not supported in " + + this.getClass().getSimpleName()); + } +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JEntityReader.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JEntityReader.java new file mode 100644 index 000000000..5f93d7782 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JEntityReader.java @@ -0,0 +1,46 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.util.List; + +import com.impetus.kundera.client.Client; +import com.impetus.kundera.client.EnhanceEntity; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.persistence.AbstractEntityReader; +import com.impetus.kundera.persistence.EntityReader; + +/** + * Entity Reader for Neo4J + * + * @author amresh.singh + */ +public class Neo4JEntityReader extends AbstractEntityReader implements EntityReader +{ + + @Override + public EnhanceEntity findById(Object primaryKey, EntityMetadata m, Client client) + { + return super.findById(primaryKey, m, client); + } + + @Override + public List populateRelation(EntityMetadata m, Client client, int maxResults) + { + throw new UnsupportedOperationException("Method supported not required for Neo4J"); + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JTransaction.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JTransaction.java new file mode 100644 index 000000000..9f46a0cd3 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/Neo4JTransaction.java @@ -0,0 +1,177 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Transaction; + +import com.impetus.kundera.persistence.TransactionResource; + +/** + * Defines transaction boundaries for Neo4J client, in case user opts for + * transaction support (kundera.transaction.resource) + * + * @author amresh.singh + */ +public class Neo4JTransaction implements TransactionResource +{ + /** Whether this transaction is currently in progress */ + private boolean isTransactionInProgress; + + /** IDs of nodes participating in this transaction */ + private List nodeIds; + + private Map processedNodes; + + /** + * Instance of {@link GraphDatabaseService} from which this transaction was + * spawned + */ + GraphDatabaseService graphDb = null; + + /** Neo4J Transaction instance */ + Transaction tx = null; + + @Override + public void onBegin() + { + if (graphDb != null && !isTransactionInProgress) + { + tx = graphDb.beginTx(); + nodeIds = new ArrayList(); + processedNodes = new HashMap(); + } + + isTransactionInProgress = true; + } + + @Override + public void onCommit() + { + if (tx != null && isTransactionInProgress) + { + tx.success(); + tx.finish(); + nodeIds.clear(); + processedNodes.clear(); + } + + isTransactionInProgress = false; + } + + @Override + public void onRollback() + { + if (tx != null && isTransactionInProgress) + { + tx.failure(); + tx.finish(); + nodeIds.clear(); + processedNodes.clear(); + } + + tx = null; + isTransactionInProgress = false; + } + + @Override + public void onFlush() + { + onCommit(); + } + + @Override + public Response prepare() + { + return Response.YES; + } + + @Override + public boolean isActive() + { + return isTransactionInProgress; + } + + /** + * @return the graphDb + */ + public GraphDatabaseService getGraphDb() + { + return graphDb; + } + + /** + * @param graphDb + * the graphDb to set + */ + public void setGraphDb(GraphDatabaseService graphDb) + { + this.graphDb = graphDb; + } + + /** + * @param nodeIds + * the nodeIds to set + */ + public void addNodeId(Long nodeId) + { + if (nodeIds == null) + { + nodeIds = new ArrayList(); + } + nodeIds.add(nodeId); + } + + public boolean containsNodeId(Long nodeId) + { + if (nodeIds == null) + return false; + + return nodeIds.contains(nodeId); + } + + /** + * @return the processedNodes + */ + public Node getProcessedNode(Object key) + { + if (processedNodes == null || processedNodes.isEmpty()) + { + return null; + } + return processedNodes.get(key); + } + + /** + * @param processedNodes + * the processedNodes to set + */ + public void addProcessedNode(Object key, Node processedNode) + { + if (processedNodes == null) + { + processedNodes = new HashMap(); + } + processedNodes.put(key, processedNode); + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/config/Neo4JPropertyReader.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/config/Neo4JPropertyReader.java new file mode 100644 index 000000000..4ca76dc60 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/config/Neo4JPropertyReader.java @@ -0,0 +1,119 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.config; + +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.configure.AbstractPropertyReader; +import com.impetus.kundera.configure.ClientProperties; +import com.impetus.kundera.configure.ClientProperties.DataStore; +import com.impetus.kundera.configure.PropertyReader; + +/** + * XML Property reader for Neo4J specific configuration + * + * @author amresh.singh + */ +public class Neo4JPropertyReader extends AbstractPropertyReader implements PropertyReader +{ + + /** log instance */ + private static Logger log = LoggerFactory.getLogger(Neo4JPropertyReader.class); + + /** Neo4J schema metadata instance */ + public static Neo4JSchemaMetadata nsmd; + + public Neo4JPropertyReader(Map externalProperties) + { + super(externalProperties); + nsmd = new Neo4JSchemaMetadata(); + } + + /** + * Sets Client properties from XML configuration file into + * {@link Neo4JSchemaMetadata} + */ + @Override + protected void onXml(ClientProperties cp) + { + if (cp != null) + { + nsmd.setClientProperties(cp); + } + } + + /** + * Holds property related to Neo4J specific configuration file + * + * @author Amresh + * + */ + public class Neo4JSchemaMetadata + { + private static final String NEO4J_DATASTORE = "neo4j"; + + private ClientProperties clientProperties; + + public Neo4JSchemaMetadata() + { + + } + + /** + * @return the clientProperties + */ + public ClientProperties getClientProperties() + { + return clientProperties; + } + + /** + * @param clientProperties + * the clientProperties to set + */ + private void setClientProperties(ClientProperties clientProperties) + { + this.clientProperties = clientProperties; + } + + /** + * Returns datastore instance for given {@link ClientProperties} for + * Neo4j + * + * @return + */ + public DataStore getDataStore() + { + if (getClientProperties() != null && getClientProperties().getDatastores() != null) + { + for (DataStore dataStore : getClientProperties().getDatastores()) + { + if (dataStore.getName() != null && dataStore.getName().equalsIgnoreCase(NEO4J_DATASTORE)) + { + return dataStore; + } + } + } + return null; + } + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/index/Neo4JIndexManager.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/index/Neo4JIndexManager.java new file mode 100644 index 000000000..80091d4b7 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/index/Neo4JIndexManager.java @@ -0,0 +1,301 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.index; + +import java.lang.reflect.Field; +import java.util.Map; +import java.util.Set; + +import javax.persistence.metamodel.Attribute; + +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.index.Index; +import org.neo4j.helpers.collection.MapUtil; +import org.neo4j.unsafe.batchinsert.BatchInserterIndex; +import org.neo4j.unsafe.batchinsert.BatchInserterIndexProvider; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.MetamodelImpl; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; + +/** + * Provides functionalities specific to Auto/ Manual Indexing + * + * @author amresh.singh + */ +public class Neo4JIndexManager +{ + // Auto-Indexing related methods + public boolean isNodeAutoIndexingEnabled(GraphDatabaseService graphDb) + { + return graphDb.index().getNodeAutoIndexer().isEnabled(); + } + + public boolean isRelationshipAutoIndexingEnabled(GraphDatabaseService graphDb) + { + return graphDb.index().getRelationshipAutoIndexer().isEnabled(); + } + + public Set getNodeIndexedProperties(GraphDatabaseService graphDb) + { + return graphDb.index().getNodeAutoIndexer().getAutoIndexedProperties(); + } + + public Set getRelationsipIndexedProperties(GraphDatabaseService graphDb) + { + return graphDb.index().getRelationshipAutoIndexer().getAutoIndexedProperties(); + } + + protected boolean isEntityForNeo4J(EntityMetadata entityMetadata) + { + String persistenceUnit = entityMetadata.getPersistenceUnit(); + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + String clientFactory = puMetadata.getProperty(PersistenceProperties.KUNDERA_CLIENT_FACTORY); + if (clientFactory.indexOf("com.impetus.client.neo4j") >= 0) + { + return true; + } + return false; + } + + /**************** Manual Indexing related methods *********************/ + + /** + * If node auto-indexing is disabled,manually index this Node + * + * @param entityMetadata + * @param graphDb + * @param autoIndexing + * @param node + */ + public void indexNode(EntityMetadata entityMetadata, GraphDatabaseService graphDb, Node node) + { + if (!isNodeAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index nodeIndex = graphDb.index().forNodes(entityMetadata.getIndexName()); + addNodeIndex(entityMetadata, node, nodeIndex); + } + } + + /** + * If relationship auto-indexing is disabled, manually index this + * relationship + * + * @param entityMetadata + * @param graphDb + * @param autoIndexing + * @param node + */ + public void indexRelationship(EntityMetadata entityMetadata, GraphDatabaseService graphDb, Relationship relationship) + { + if (!isRelationshipAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index relationshipIndex = graphDb.index().forRelationships(entityMetadata.getIndexName()); + addRelationshipIndex(entityMetadata, relationship, relationshipIndex); + } + } + + public void indexNodeUsingBatchIndexer(BatchInserterIndexProvider indexProvider, EntityMetadata entityMetadata, + long nodeId, Map nodeProperties, boolean nodeAutoIndexingEnabled) + { + BatchInserterIndex nodeIndex = null; + + if (!nodeAutoIndexingEnabled && entityMetadata.isIndexable()) + { + nodeIndex = indexProvider.nodeIndex(entityMetadata.getIndexName(), MapUtil.stringMap("type", "exact")); + + } + else + { + nodeIndex = indexProvider.nodeIndex("node_auto_index", MapUtil.stringMap("type", "exact")); + } + + if (nodeIndex != null) + nodeIndex.add(nodeId, nodeProperties); + } + + public void indexRelationshipUsingBatchIndexer(BatchInserterIndexProvider indexProvider, + EntityMetadata entityMetadata, long relationshipId, Map relationshipProperties, + boolean relationshipAutoIndexingEnabled) + { + BatchInserterIndex relationshipIndex = null; + + if (!relationshipAutoIndexingEnabled && entityMetadata.isIndexable()) + { + relationshipIndex = indexProvider.relationshipIndex(entityMetadata.getIndexName(), + MapUtil.stringMap("type", "exact")); + } + else + { + relationshipIndex = indexProvider.relationshipIndex("relationship_auto_index", + MapUtil.stringMap("type", "exact")); + } + + if (relationshipIndex != null) + relationshipIndex.add(relationshipId, relationshipProperties); + } + + /** + * If node auto-indexing is disabled, Update index for this node manually + * + * @param entityMetadata + * @param graphDb + * @param autoIndexing + * @param node + */ + public void updateNodeIndex(EntityMetadata entityMetadata, GraphDatabaseService graphDb, Node node) + { + if (!isNodeAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index nodeIndex = graphDb.index().forNodes(entityMetadata.getIndexName()); + + // Remove all exiting node entries from Index + nodeIndex.remove(node); + + // Recreate fresh index on this node + addNodeIndex(entityMetadata, node, nodeIndex); + } + + } + + /** + * If relationship auto-indexing is disabled, Update index for this + * relationship manually + * + * @param entityMetadata + * @param graphDb + * @param autoIndexing + * @param node + */ + public void updateRelationshipIndex(EntityMetadata entityMetadata, GraphDatabaseService graphDb, + Relationship relationship) + { + if (!isRelationshipAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index relationshipIndex = graphDb.index().forRelationships(entityMetadata.getIndexName()); + + // Remove all existing relationship entries from Index + relationshipIndex.remove(relationship); + + // Recreate fresh index on this relationship + addRelationshipIndex(entityMetadata, relationship, relationshipIndex); + } + } + + /** + * Deletes a {@link Node} from manually created index if auto-indexing is + * disabled + * + * @param entityMetadata + * @param graphDb + * @param node + */ + public void deleteNodeIndex(EntityMetadata entityMetadata, GraphDatabaseService graphDb, Node node) + { + if (!isNodeAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index nodeIndex = graphDb.index().forNodes(entityMetadata.getIndexName()); + nodeIndex.remove(node); + } + } + + /** + * Deletes a {@link Relationship} from manually created index if + * auto-indexing is disabled + * + * @param entityMetadata + * @param graphDb + * @param relationship + */ + public void deleteRelationshipIndex(EntityMetadata entityMetadata, GraphDatabaseService graphDb, + Relationship relationship) + { + if (!isRelationshipAutoIndexingEnabled(graphDb) && entityMetadata.isIndexable()) + { + Index relationshipIndex = graphDb.index().forRelationships(entityMetadata.getIndexName()); + relationshipIndex.remove(relationship); + } + } + + /** + * Adds Node Index for all singular attributes (including ID) of a given + * entity + * + * @param entityMetadata + * @param node + * @param metaModel + * @param nodeIndex + */ + private void addNodeIndex(EntityMetadata entityMetadata, Node node, Index nodeIndex) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + // ID attribute has to be indexed necessarily + String idColumnName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName(); + nodeIndex.add(node, idColumnName, node.getProperty(idColumnName)); + + // Index all other fields, for whom indexing is enabled + for (Attribute attribute : metaModel.entity(entityMetadata.getEntityClazz()).getSingularAttributes()) + { + Field field = (Field) attribute.getJavaMember(); + if (!attribute.isCollection() && !attribute.isAssociation() + && entityMetadata.getIndexProperties().keySet().contains(field.getName())) + { + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + nodeIndex.add(node, columnName, node.getProperty(columnName)); + } + } + } + + /** + * Adds Relationship Index for all singular attributes (including ID) of a + * given relationship entity + * + * @param entityMetadata + * @param graphDb + * @param relationship + */ + private void addRelationshipIndex(EntityMetadata entityMetadata, Relationship relationship, + Index relationshipIndex) + { + MetamodelImpl metaModel = (MetamodelImpl) KunderaMetadata.INSTANCE.getApplicationMetadata().getMetamodel( + entityMetadata.getPersistenceUnit()); + + // ID attribute has to be indexed first + String idColumnName = ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName(); + relationshipIndex.add(relationship, idColumnName, relationship.getProperty(idColumnName)); + + // Index all other fields, for whom indexing is enabled + for (Attribute attribute : metaModel.entity(entityMetadata.getEntityClazz()).getSingularAttributes()) + { + Field field = (Field) attribute.getJavaMember(); + if (!attribute.isCollection() && !attribute.isAssociation() + && entityMetadata.getIndexProperties().keySet().contains(field.getName())) + { + String columnName = ((AbstractAttribute) attribute).getJPAColumnName(); + relationshipIndex.add(relationship, columnName, relationship.getProperty(columnName)); + } + } + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JLuceneQuery.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JLuceneQuery.java new file mode 100644 index 000000000..f06bda948 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JLuceneQuery.java @@ -0,0 +1,41 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.query; + +import java.util.ArrayList; +import java.util.List; + +import com.impetus.client.neo4j.Neo4JClient; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Lucene implementation of {@link Neo4JNativeQuery} + * + * @author amresh.singh + */ +public class Neo4JLuceneQuery implements Neo4JNativeQuery +{ + + @Override + public List executeNativeQuery(String nativeQuery, Neo4JClient client, EntityMetadata m) + { + List entities = new ArrayList(); + + entities = client.executeLuceneQuery(m, nativeQuery); + + return entities; + } +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQuery.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQuery.java new file mode 100644 index 000000000..0b1f8a019 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQuery.java @@ -0,0 +1,33 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.query; + +import java.util.List; + +import com.impetus.client.neo4j.Neo4JClient; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Interface for Neo4J Native queries + * + * @author amresh.singh + */ +public interface Neo4JNativeQuery +{ + + public List executeNativeQuery(String nativeQuery, Neo4JClient client, EntityMetadata m); + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQueryFactory.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQueryFactory.java new file mode 100644 index 000000000..dcc47c355 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JNativeQueryFactory.java @@ -0,0 +1,48 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.query; + +import com.impetus.kundera.query.QueryHandlerException; + +/** + * factory for {@link Neo4JNativeQuery} + * + * @author amresh.singh + */ +public class Neo4JNativeQueryFactory +{ + public static Neo4JNativeQuery getNativeQueryImplementation(Neo4JQueryType queryType) + { + if (queryType.equals(Neo4JQueryType.LUCENE)) + { + return new Neo4JLuceneQuery(); + } + /* + * else if (queryType.equals(Neo4JQueryType.CYPHER)) { return new + * Neo4JCypherQuery(); } + */ + /* + * else if (queryType.equals(Neo4JQueryType.GREMLIN)) { + * + * } + */ + else + { + throw new QueryHandlerException("Invalid Query Type:" + queryType + + ".Can't determine and implementation for running this type for native query for Neo4J"); + } + } +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQuery.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQuery.java new file mode 100644 index 000000000..c83684124 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQuery.java @@ -0,0 +1,215 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.query; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.impetus.client.neo4j.Neo4JClient; +import com.impetus.client.neo4j.Neo4JEntityReader; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.model.ApplicationMetadata; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.attributes.AbstractAttribute; +import com.impetus.kundera.persistence.EntityReader; +import com.impetus.kundera.persistence.PersistenceDelegator; +import com.impetus.kundera.query.KunderaQuery; +import com.impetus.kundera.query.KunderaQuery.FilterClause; +import com.impetus.kundera.query.QueryImpl; + +/** + * Neo4J Query Implementor + * + * @author amresh.singh + */ +public class Neo4JQuery extends QueryImpl +{ + private static final String NATIVE_QUERY_TYPE = "native.query.type"; + + Neo4JQueryType queryType; + + /** The reader. */ + private EntityReader reader; + + /** + * @param query + * @param persistenceDelegator + */ + public Neo4JQuery(String query, KunderaQuery kunderaQuery, PersistenceDelegator persistenceDelegator) + { + super(query, persistenceDelegator); + this.kunderaQuery = kunderaQuery; + if (getHints().containsKey(NATIVE_QUERY_TYPE)) + { + queryType = (Neo4JQueryType) getHints().get(NATIVE_QUERY_TYPE); + } + else + { + queryType = Neo4JQueryType.LUCENE; + } + + } + + @Override + protected List populateEntities(EntityMetadata m, Client client) + { + // One implementation for entities with or without relations + return recursivelyPopulateEntities(m, client); + } + + @Override + protected List recursivelyPopulateEntities(EntityMetadata m, Client client) + { + List entities = new ArrayList(); + ApplicationMetadata appMetadata = KunderaMetadata.INSTANCE.getApplicationMetadata(); + + if (appMetadata.isNative(getJPAQuery())) + { + String nativeQuery = appMetadata.getQuery(getJPAQuery()); + Neo4JNativeQuery nativeQueryImpl = Neo4JNativeQueryFactory.getNativeQueryImplementation(queryType); + entities = nativeQueryImpl.executeNativeQuery(nativeQuery, (Neo4JClient) client, m); + } + else + { + String luceneQuery = getLuceneQuery(kunderaQuery); + entities = ((Neo4JClient) client).executeLuceneQuery(m, luceneQuery); + } + return setRelationEntities(entities, client, m); + } + + @Override + protected EntityReader getReader() + { + if (reader == null) + { + reader = new Neo4JEntityReader(); + } + return reader; + } + + @Override + protected int onExecuteUpdate() + { + if (kunderaQuery.isDeleteUpdate()) + { + List result = getResultList(); + return result != null ? result.size() : 0; + } + + return 0; + } + + private String getLuceneQuery(KunderaQuery kunderaQuery) + { + StringBuffer sb = new StringBuffer(); + + if (kunderaQuery.getFilterClauseQueue().isEmpty()) + { + // Select All query if filter clause is empty + String idColumnName = ((AbstractAttribute) kunderaQuery.getEntityMetadata().getIdAttribute()) + .getJPAColumnName(); + sb.append(idColumnName).append(":").append("*"); + } + else + { + for (Object object : kunderaQuery.getFilterClauseQueue()) + { + if (object instanceof FilterClause) + { + boolean appended = false; + FilterClause filter = (FilterClause) object; + // property + sb.append(filter.getProperty()); + + // joiner + String appender = ""; + if (filter.getCondition().equals("=")) + { + sb.append(":"); + } + else if (filter.getCondition().equalsIgnoreCase("like")) + { + sb.append(":"); + appender = "*"; + } + else if (filter.getCondition().equalsIgnoreCase(">")) + { + // TODO: Amresh need to look for "String.class" + // parameter. + sb.append(appendRange(filter.getValue().toString(), false, true, String.class)); + appended = true; + } + else if (filter.getCondition().equalsIgnoreCase(">=")) + { + sb.append(appendRange(filter.getValue().toString(), true, true, String.class)); + appended = true; + } + else if (filter.getCondition().equalsIgnoreCase("<")) + { + sb.append(appendRange(filter.getValue().toString(), false, false, String.class)); + appended = true; + } + else if (filter.getCondition().equalsIgnoreCase("<=")) + { + sb.append(appendRange(filter.getValue().toString(), true, false, String.class)); + appended = true; + } + + // value. if not already appended. + if (!appended) + { + if (appender.equals("") && filter.getValue() != null + && filter.getValue().toString().contains(" ")) + { + sb.append("\""); + sb.append(filter.getValue().toString()); + sb.append("\""); + } + else + { + sb.append(filter.getValue()); + sb.append(appender); + } + + } + } + else + { + sb.append(" " + object + " "); + } + } + } + + return sb.toString(); + } + + @Override + public void close() + { + // TODO Auto-generated method stub + + } + + @Override + public Iterator iterate() + { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQueryType.java b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQueryType.java new file mode 100644 index 000000000..01c1d29e8 --- /dev/null +++ b/src/kundera-neo4j/src/main/java/com/impetus/client/neo4j/query/Neo4JQueryType.java @@ -0,0 +1,27 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.query; + +/** + * Enum for different native query types supported in Neo4J Currently, only + * Lucene is supported, rest are for future use. + * + * @author amresh.singh + */ +public enum Neo4JQueryType +{ + LUCENE, CYPHER, GREMLIN +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/GraphEntityMapperTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/GraphEntityMapperTest.java new file mode 100644 index 000000000..49a8d7c61 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/GraphEntityMapperTest.java @@ -0,0 +1,314 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.io.File; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.neo4j.graphdb.DynamicRelationshipType; +import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; +import org.neo4j.graphdb.Relationship; +import org.neo4j.graphdb.Transaction; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.client.neo4j.imdb.Actor; +import com.impetus.client.neo4j.imdb.Movie; +import com.impetus.client.neo4j.imdb.Role; +import com.impetus.client.neo4j.index.Neo4JIndexManager; +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Test case for {@link GraphEntityMapper} + * + * @author amresh.singh + */ +public class GraphEntityMapperTest +{ + static EntityManagerFactory emf; + + static EntityManager em; + + static Neo4JClient client; + + GraphEntityMapper mapper; + + GraphDatabaseService graphDb; + + final static String PU = "imdb"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + emf = Persistence.createEntityManagerFactory(PU); + em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + client = (Neo4JClient) clients.get(PU); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + emf.close(); + + if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath)); + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + mapper = new GraphEntityMapper(new Neo4JIndexManager()); + graphDb = client.getConnection(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + mapper = null; + graphDb = null; + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#getNodeFromEntity(java.lang.Object, Object, org.neo4j.graphdb.GraphDatabaseService, com.impetus.kundera.metadata.model.EntityMetadata, boolean)} + * . + */ + @Test + public void testGetNodeFromEntity() + { + Actor actor = new Actor(); + actor.setId(1); + actor.setName("Keenu Reeves"); + + Transaction tx = graphDb.beginTx(); + Node node = mapper.getNodeFromEntity(actor, 1, graphDb, KunderaMetadataManager.getEntityMetadata(Actor.class), + false); + Assert.assertNotNull(node); + Assert.assertEquals(1, node.getProperty("ACTOR_ID")); + Assert.assertEquals("Keenu Reeves", node.getProperty("ACTOR_NAME")); + + node.delete(); + + tx.success(); + tx.finish(); + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#createProxyNode(java.lang.Object, java.lang.Object, org.neo4j.graphdb.GraphDatabaseService, com.impetus.kundera.metadata.model.EntityMetadata, com.impetus.kundera.metadata.model.EntityMetadata)} + * . + */ + @Test + public void testCreateProxyNode() + { + EntityMetadata sourceM = KunderaMetadataManager.getEntityMetadata(Actor.class); + EntityMetadata targetM = KunderaMetadataManager.getEntityMetadata(Movie.class); + + Transaction tx = graphDb.beginTx(); + Node proxyNode = mapper.createProxyNode(1, "A", graphDb, sourceM, targetM); + + Assert.assertNotNull(proxyNode); + Assert.assertEquals(1, proxyNode.getProperty("ACTOR_ID")); + Assert.assertEquals("A", proxyNode.getProperty("MOVIE_ID")); + Assert.assertEquals("$PROXY_NODE$", proxyNode.getProperty("$NODE_TYPE$")); + + proxyNode.delete(); + tx.success(); + tx.finish(); + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#getEntityFromNode(org.neo4j.graphdb.Node, com.impetus.kundera.metadata.model.EntityMetadata)} + * . + */ + @Test + public void testGetEntityFromNode() + { + Transaction tx = graphDb.beginTx(); + Node node = graphDb.createNode(); + node.setProperty("ACTOR_ID", 1); + node.setProperty("ACTOR_NAME", "Amresh Singh"); + + Actor actor = (Actor) mapper.getEntityFromNode(node, KunderaMetadataManager.getEntityMetadata(Actor.class)); + + Assert.assertNotNull(actor); + Assert.assertEquals(1, actor.getId()); + Assert.assertEquals("Amresh Singh", actor.getName()); + + node.delete(); + tx.success(); + tx.finish(); + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#getEntityFromRelationship(org.neo4j.graphdb.Relationship, com.impetus.kundera.metadata.model.EntityMetadata, com.impetus.kundera.metadata.model.Relation)} + * . + */ + @Test + public void testGetEntityFromRelationship() + { + Transaction tx = graphDb.beginTx(); + Node sourceNode = graphDb.createNode(); + sourceNode.setProperty("ACTOR_ID", 1); + sourceNode.setProperty("ACTOR_NAME", "Amresh Singh"); + + Node targetNode = graphDb.createNode(); + targetNode.setProperty("MOVIE_ID", "M1"); + targetNode.setProperty("TITLE", "Matrix Reloaded"); + targetNode.setProperty("YEAR", 1999); + + Relationship rel = sourceNode.createRelationshipTo(targetNode, DynamicRelationshipType.withName("ACTS_IN")); + rel.setProperty("ROLE_NAME", "Neo"); + rel.setProperty("ROLE_TYPE", "Lead Actor"); + + Role role = (Role) mapper.getEntityFromRelationship(rel, KunderaMetadataManager.getEntityMetadata(Actor.class), + KunderaMetadataManager.getEntityMetadata(Actor.class).getRelation("movies")); + + Assert.assertNotNull(role); + Assert.assertEquals("Neo", role.getRoleName()); + Assert.assertEquals("Lead Actor", role.getRoleType()); + + rel.delete(); + sourceNode.delete(); + targetNode.delete(); + + tx.success(); + tx.finish(); + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#createNodeProperties(java.lang.Object, com.impetus.kundera.metadata.model.EntityMetadata)} + * . + */ + @Test + public void testCreateNodeProperties() + { + Actor actor = new Actor(); + actor.setId(1); + actor.setName("Keenu Reeves"); + + EntityMetadata m = KunderaMetadataManager.getEntityMetadata(Actor.class); + + Map props = mapper.createNodeProperties(actor, m); + Assert.assertNotNull(props); + Assert.assertFalse(props.isEmpty()); + Assert.assertEquals(1, props.get("ACTOR_ID")); + Assert.assertEquals("Keenu Reeves", props.get("ACTOR_NAME")); + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#populateRelationshipProperties(com.impetus.kundera.metadata.model.EntityMetadata, com.impetus.kundera.metadata.model.EntityMetadata, org.neo4j.graphdb.Relationship, java.lang.Object)} + * . + */ + @Test + public void testPopulateRelationshipProperties() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#createRelationshipProperties(com.impetus.kundera.metadata.model.EntityMetadata, com.impetus.kundera.metadata.model.EntityMetadata, java.lang.Object)} + * . + */ + @Test + public void testCreateRelationshipProperties() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#toNeo4JProperty(java.lang.Object)} + * . + */ + @Test + public void testToNeo4JProperty() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#fromNeo4JObject(java.lang.Object, java.lang.reflect.Field)} + * . + */ + @Test + public void testFromNeo4JObject() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#searchNode(java.lang.Object, com.impetus.kundera.metadata.model.EntityMetadata, org.neo4j.graphdb.GraphDatabaseService, boolean)} + * . + */ + @Test + public void testSearchNode() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.GraphEntityMapper#getMatchingNodeFromIndexHits(org.neo4j.graphdb.index.IndexHits, boolean)} + * . + */ + @Test + public void testGetMatchingNodeFromIndexHits() + { + + } + +} \ No newline at end of file diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientFactoryTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientFactoryTest.java new file mode 100644 index 000000000..ef1656e69 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientFactoryTest.java @@ -0,0 +1,135 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.neo4j.kernel.EmbeddedGraphDatabase; +import org.neo4j.kernel.impl.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.ClientResolver; +import com.impetus.kundera.loader.ClientFactory; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Test case for {@link Neo4JClientFactory} + * + * @author amresh.singh + */ +public class Neo4JClientFactoryTest +{ + + /** The Constant REDIS_PU. */ + private static final String persistenceUnit = "imdb"; + + /** The emf. */ + private EntityManagerFactory emf; + + /** The logger. */ + private static Logger logger = LoggerFactory.getLogger(Neo4JClientFactoryTest.class); + + /** + * Setup. + */ + @Before + public void setup() + { + emf = Persistence.createEntityManagerFactory(persistenceUnit); + } + + /** + * Test connection. + */ + @Test + public void testConnection() + { + logger.info("On test connection"); + + ClientFactory clientFactory = ClientResolver.getClientFactory(persistenceUnit); + Assert.assertNotNull(clientFactory); + Assert.assertEquals(Neo4JClientFactory.class, clientFactory.getClass()); + Field connectionField; + try + { + String field_name = "connectionPoolOrConnection"; + connectionField = ((Neo4JClientFactory) clientFactory).getClass().getSuperclass() + .getDeclaredField(field_name); + + if (!connectionField.isAccessible()) + { + connectionField.setAccessible(true); + } + + Object connectionObj = connectionField.get(clientFactory); + + Assert.assertNotNull(connectionObj); + Assert.assertTrue(connectionObj instanceof EmbeddedGraphDatabase); + + } + catch (SecurityException e) + { + logger.error(e.getMessage()); + Assert.fail(e.getMessage()); + } + catch (NoSuchFieldException e) + { + logger.error(e.getMessage()); + Assert.fail(e.getMessage()); + } + catch (IllegalArgumentException e) + { + logger.error(e.getMessage()); + Assert.fail(e.getMessage()); + } + catch (IllegalAccessException e) + { + logger.error(e.getMessage()); + Assert.fail(e.getMessage()); + } + + } + + /** + * Tear down. + * @throws IOException + */ + @After + public void tearDown() throws IOException + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(persistenceUnit); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + emf.close(); + + if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath)); + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientTest.java new file mode 100644 index 000000000..2fdc93c8c --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/Neo4JClientTest.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * * Copyright 2012 Impetus Infotech. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + ******************************************************************************/ +package com.impetus.client.neo4j; + +import java.io.File; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.client.Client; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * @author amresh + * + */ +public class Neo4JClientTest +{ + static EntityManagerFactory emf; + + static EntityManager em; + + static Neo4JClient client; + + GraphEntityMapper mapper; + + final static String PU = "imdb"; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + emf = Persistence.createEntityManagerFactory(PU); + em = emf.createEntityManager(); + Map clients = (Map) em.getDelegate(); + client = (Neo4JClient) clients.get(PU); + } + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + emf.close(); + + /* if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath));*/ + } + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#onPersist(com.impetus.kundera.metadata.model.EntityMetadata, java.lang.Object, java.lang.Object, java.util.List)} + * . + */ + @Test + public void testOnPersist() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#find(java.lang.Class, java.lang.Object)} + * . + */ + @Test + public void testFindClassObject() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#findAll(java.lang.Class, String[], java.lang.Object[])} + * . + */ + @Test + public void testFindAll() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#delete(java.lang.Object, java.lang.Object)} + * . + */ + @Test + public void testDelete() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#persistJoinTable(com.impetus.kundera.persistence.context.jointable.JoinTableData)} + * . + */ + @Test + public void testPersistJoinTable() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#getColumnsById(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object)} + * . + */ + @Test + public void testGetColumnsById() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#findIdsByColumn(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Object, java.lang.Class)} + * . + */ + @Test + public void testFindIdsByColumn() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#deleteByColumn(java.lang.String, java.lang.String, java.lang.String, java.lang.Object)} + * . + */ + @Test + public void testDeleteByColumn() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#findByRelation(java.lang.String, java.lang.Object, java.lang.Class)} + * . + */ + @Test + public void testFindByRelation() + { + + } + + /** + * Test method for {@link com.impetus.client.neo4j.Neo4JClient#getReader()}. + */ + @Test + public void testGetReader() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#getQueryImplementor()}. + */ + @Test + public void testGetQueryImplementor() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#addBatch(com.impetus.kundera.graph.Node)} + * . + */ + @Test + public void testAddBatch() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#executeBatch()}. + */ + @Test + public void testExecuteBatch() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#getBatchInserter()}. + */ + @Test + public void testGetBatchInserter() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#bind(com.impetus.kundera.persistence.TransactionResource)} + * . + */ + @Test + public void testBind() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#executeLuceneQuery(com.impetus.kundera.metadata.model.EntityMetadata, java.lang.String)} + * . + */ + @Test + public void testExecuteLuceneQuery() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClient#getConnection()}. + */ + @Test + public void testGetConnection() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClientBase#isEntityForNeo4J(com.impetus.kundera.metadata.model.EntityMetadata)} + * . + */ + @Test + public void testIsEntityForNeo4J() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClientBase#populateBatchSize(java.lang.String, java.util.Map)} + * . + */ + @Test + public void testPopulateBatchSize() + { + + } + + /** + * Test method for + * {@link com.impetus.client.neo4j.Neo4JClientBase#getBatchSize()}. + */ + @Test + public void testGetBatchSize() + { + + } + + /** + * Test method for {@link com.impetus.client.neo4j.Neo4JClientBase#clear()}. + */ + @Test + public void testClear() + { + + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Actor.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Actor.java new file mode 100644 index 000000000..0bcf23fd1 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Actor.java @@ -0,0 +1,129 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.MapKeyJoinColumn; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Actor Node Entity class + * + * @author amresh.singh + */ + +@Entity +@Table +// Ignored for Neo4J +@IndexCollection(columns = { @Index(name = "name", type = "KEYS") }) +public class Actor +{ + @Id + @Column(name = "ACTOR_ID") + private int id; + + @Column(name = "ACTOR_NAME") + private String name; + + public Actor() + { + } + + public Actor(int actorId, String actorName) + { + this.id = actorId; + this.name = actorName; + } + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + /* + * @JoinTable(name = "ACTOR_MOVIE", //Ignored in case Movie isn't stored in + * Neo4J joinColumns = { @JoinColumn(name = "ACTOR_ID") }, + * inverseJoinColumns = { @JoinColumn(name = "MOVIE_ID") }) + */ + @MapKeyJoinColumn(name = "ACTS_IN") + private Map movies; + + public void addMovie(Role role, Movie movie) + { + if (movies == null) + movies = new HashMap(); + movies.put(role, movie); + } + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the movies + */ + public Map getMovies() + { + return movies; + } + + /** + * @param movies + * the movies to set + */ + public void setMovies(Map movies) + { + this.movies = movies; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBBatchInsertionTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBBatchInsertionTest.java new file mode 100644 index 000000000..b2be3157b --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBBatchInsertionTest.java @@ -0,0 +1,152 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Test case demonstrating batch insertion in Neo4J + * + * @author amresh.singh + */ +public class IMDBBatchInsertionTest +{ + private static final String IMDB_BATCH_PU = "imdbBatch"; + + EntityManagerFactory emf; + + EntityManager em; + + final int n = 4; // Number of actors + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + Map properties = new HashMap(); + properties.put(PersistenceProperties.KUNDERA_BATCH_SIZE, "5"); + emf = Persistence.createEntityManagerFactory(IMDB_BATCH_PU, properties); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(IMDB_BATCH_PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + emf.close(); + + if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath)); + } + + @Test + public void batchTest() + { + + List actors = prepareData(n); + + for (Actor actor : actors) + { + if (actor != null) + { + em.persist(actor); + } + } + } + + /** + * n = number of Actors + * + * @param n + * @return + */ + private List prepareData(int n) + { + List actors = new ArrayList(); + actors.add(0, null); + List movies = new ArrayList(); + movies.add(0, null); + List roles = new ArrayList(); + roles.add(0, null); + + for (int i = 1; i <= (n + 1); i++) + { + Movie movie = new Movie("" + i, "Movie " + i, (2000 + i)); + movies.add(i, movie); + } + + for (int i = 1; i <= 2 * n; i++) + { + Role role = new Role("Role " + i, "Role Type " + i); + roles.add(i, role); + } + + for (int i = 1; i <= n; i++) + { + Actor actor = new Actor(i, "Actor " + i); + actors.add(i, actor); + + } + + for (int i = 1; i <= n; i++) + { + Actor actor = actors.get(i); + actor.addMovie(roles.get(2 * i - 1), movies.get(i)); + actor.addMovie(roles.get(2 * i), movies.get(i + 1)); + + if (i == 1) + { + movies.get(i).addActor(roles.get(i), actor); + } + else + { + movies.get(i).addActor(roles.get(2 * i - 2), actors.get(i - 1)); + movies.get(i).addActor(roles.get(2 * i - 1), actors.get(i)); + } + } + movies.get(n + 1).addActor(roles.get(2 * n), actors.get(n)); + + return actors; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBCRUDTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBCRUDTest.java new file mode 100644 index 000000000..2d1a495ec --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBCRUDTest.java @@ -0,0 +1,136 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Test case using IMDB example for CRUD Demonstrates M-2-M Association between + * two entitites using Map + * + * @author amresh.singh + */ +public class IMDBCRUDTest extends IMDBTestBase +{ + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + init(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + clean(); + } + + @Test + public void testCRUD() + { + // CRUD + insert(); + find(); + merge(); + delete(); + } + + private void insert() + { + populateActors(); + + em.getTransaction().begin(); + + em.persist(actor1); + em.persist(actor2); + + em.getTransaction().commit(); + + } + + private void find() + { + // Find actor by ID + em.clear(); + + Actor actor1 = em.find(Actor.class, 1); + Actor actor2 = em.find(Actor.class, 2); + + assertActors(actor1, actor2); + + } + + private void merge() + { + Actor actor1 = em.find(Actor.class, 1); + Actor actor2 = em.find(Actor.class, 2); + + assertActors(actor1, actor2); + + actor1.setName("Amresh"); + actor2.setName("Amir"); + + em.getTransaction().begin(); + em.merge(actor1); + em.merge(actor2); + em.getTransaction().commit(); + + em.clear(); + + Actor actor1AfterMerge = em.find(Actor.class, 1); + Actor actor2AfterMerge = em.find(Actor.class, 2); + + assertUpdatedActors(actor1AfterMerge, actor2AfterMerge); + + } + + private void delete() + { + Actor actor1 = em.find(Actor.class, 1); + Actor actor2 = em.find(Actor.class, 2); + assertUpdatedActors(actor1, actor2); + + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + + em.clear(); // clear cache + Actor actor1AfterDeletion = em.find(Actor.class, 1); + Actor actor2AfterDeletion = em.find(Actor.class, 2); + + Assert.assertNull(actor1AfterDeletion); + Assert.assertNull(actor2AfterDeletion); + + Movie movie1AfterDeletion = em.find(Movie.class, "m1"); + Movie movie2AfterDeletion = em.find(Movie.class, "m2"); + Movie movie3AfterDeletion = em.find(Movie.class, "m3"); + + Assert.assertNull(movie1AfterDeletion); + Assert.assertNull(movie2AfterDeletion); + Assert.assertNull(movie3AfterDeletion); + + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBJPAQueriesTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBJPAQueriesTest.java new file mode 100644 index 000000000..77d2653f2 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBJPAQueriesTest.java @@ -0,0 +1,258 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.util.List; + +import javax.persistence.Query; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * * Test case using IMDB example for JPA Queries Demonstrates M-2-M Association + * between two entitites using Map + * + * @author amresh.singh + */ +public class IMDBJPAQueriesTest extends IMDBTestBase +{ + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + init(); + + // Prepare and insert data + populateActors(); + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + // Delete inserted records + Actor actor1 = em.find(Actor.class, 1); + Actor actor2 = em.find(Actor.class, 2); + + if (actor1 != null && actor2 != null) + { + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + } + + clean(); + } + + @Test + public void testJPAQueries() + { + // Select Queries + findAllActors(); + findActorByID(); + findActorByName(); + findActorByIDAndName(); + findActorWithMatchingName(); + findActorWithinGivenIdRange(); + findSelectedFields(); + findMoviesBetweenAPeriod(); + findMoviesGreaterThanLessThanYear(); + findMoviesUsingIdOrTitle(); + findMoviesUsingIdOrTitleOrYear(); + + // Delete Queries + deleteAllActors(); + + } + + private void findAllActors() + { + Query query = em.createQuery("select a from Actor a"); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(2, actors.size()); + } + + private void findActorByID() + { + Query query = em.createQuery("select a from Actor a where a.id = :id"); + query.setParameter("id", 2); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor2(actors.get(0)); + } + + private void findActorByName() + { + Query query = em.createQuery("select a from Actor a where a.name=:name"); + query.setParameter("name", "Tom Cruise"); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor1(actors.get(0)); + } + + private void findActorByIDAndName() + { + // Positive scenario + Query query = em.createQuery("select a from Actor a where a.id=:id AND a.name=:name"); + query.setParameter("id", 1); + query.setParameter("name", "Tom Cruise"); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor1(actors.get(0)); + + // Negative scenario + query = em.createQuery("select a from Actor a where a.id=:id AND a.name=:name"); + query.setParameter("id", 2); + query.setParameter("name", "Tom Cruise"); + actors = query.getResultList(); + Assert.assertTrue(actors == null || actors.isEmpty()); + } + + private void findActorWithMatchingName() + { + Query query = em.createQuery("select a from Actor a where a.name like :name"); + query.setParameter("name", "Emma"); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor2(actors.get(0)); + } + + private void findActorWithinGivenIdRange() + { + Query query = em.createQuery("select a from Actor a where a.id between :min AND :max"); + query.setParameter("min", 1); + query.setParameter("max", 2); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(2, actors.size()); + // assertActor2(actors.get(0)); + } + + private void findMoviesBetweenAPeriod() + { + // Between + Query query = em.createQuery("select m from Movie m where m.year between :start AND :end"); + query.setParameter("start", 1990); + query.setParameter("end", 2006); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + + } + + private void findMoviesGreaterThanLessThanYear() + { + // Greater-than/ Less Than + Query query = em.createQuery("select m from Movie m where m.year >= :start AND m.year <= :end"); + query.setParameter("start", 2005); + query.setParameter("end", 2010); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + } + + private void findSelectedFields() + { + Query query = em.createQuery("select a.name from Actor a"); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(2, actors.size()); + + for (Actor actor : actors) + { + Assert.assertNotNull(actor); + Assert.assertNotNull(actor.getId()); + Assert.assertNotNull(actor.getName()); + } + } + + private void findMoviesUsingIdOrTitle() + { + Query query = em.createQuery("select m from Movie m where m.id = :movieId OR m.title like :title"); + query.setParameter("movieId", "m1"); + query.setParameter("title", "Miss"); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + + for (Movie movie : movies) + { + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getId().equals("m1") || movie.getId().equals("m2")); + } + } + + private void findMoviesUsingIdOrTitleOrYear() + { + Query query = em + .createQuery("select m from Movie m where m.id = :movieId OR m.title like :title OR m.year = :year"); + query.setParameter("movieId", "m1"); + query.setParameter("title", "Miss"); + query.setParameter("year", 2009); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(3, movies.size()); + + for (Movie movie : movies) + { + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getId().equals("m1") || movie.getId().equals("m2") || movie.getId().equals("m3")); + } + } + + private void deleteAllActors() + { + em.getTransaction().begin(); + Query query = em.createQuery("delete from Actor a"); + int deleteCount = query.executeUpdate(); + em.getTransaction().commit(); + Assert.assertEquals(2, deleteCount); + + // Check whether all records have been deleted + query = em.createQuery("select a from Actor a"); + List actors = query.getResultList(); + Assert.assertTrue(actors == null || actors.isEmpty()); + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBMapMetamodelTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBMapMetamodelTest.java new file mode 100644 index 000000000..405e07271 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBMapMetamodelTest.java @@ -0,0 +1,81 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import javax.persistence.metamodel.Metamodel; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.EntityMetadata; + +/** + * Test case for validating correctness of Metamodel for Map data type + * + * @author amresh.singh + */ +public class IMDBMapMetamodelTest extends IMDBTestBase +{ + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + init(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + clean(); + } + + @Test + public void testMetamodel() + { + EntityMetadata m1 = KunderaMetadataManager.getEntityMetadata(Actor.class); + Assert.assertNotNull(m1); + Assert.assertEquals(Actor.class, m1.getEntityClazz()); + Assert.assertEquals(Role.class, m1.getRelation("movies").getMapKeyJoinClass()); + Assert.assertEquals(Movie.class, m1.getRelation("movies").getTargetEntity()); + Assert.assertEquals("ACTS_IN", m1.getRelation("movies").getJoinColumnName()); + + EntityMetadata m2 = KunderaMetadataManager.getEntityMetadata(Movie.class); + Assert.assertNotNull(m2); + Assert.assertEquals(Movie.class, m2.getEntityClazz()); + Assert.assertEquals(Role.class, m2.getRelation("actors").getMapKeyJoinClass()); + Assert.assertEquals(Actor.class, m2.getRelation("actors").getTargetEntity()); + Assert.assertNotNull(m2.getRelation("actors").getJoinColumnName()); + Assert.assertEquals(m2.getRelation("actors").getJoinColumnName(),"actors"); + + EntityMetadata m3 = KunderaMetadataManager.getEntityMetadata(Role.class); + Assert.assertNotNull(m3); + Assert.assertEquals(Role.class, m3.getEntityClazz()); + + Metamodel mm = KunderaMetadataManager.getMetamodel("imdb"); + Assert.assertNotNull(mm); + + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBNativeLuceneQueryTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBNativeLuceneQueryTest.java new file mode 100644 index 000000000..a3196fd03 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBNativeLuceneQueryTest.java @@ -0,0 +1,204 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.util.List; + +import javax.persistence.Query; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Unit test case for Native queries (Lucene) + * + * @author amresh.singh + */ +public class IMDBNativeLuceneQueryTest extends IMDBTestBase +{ + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + init(); + + // Prepare and insert data + populateActors(); + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + // Delete inserted records + Actor actor1 = em.find(Actor.class, 1); + Actor actor2 = em.find(Actor.class, 2); + + if (actor1 != null && actor2 != null) + { + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + } + + clean(); + } + + @Test + public void testLuceneQueries() + { + // Select Queries + findAllActors(); + findActorByID(); + findActorByName(); + findActorByIDAndName(); + findActorWithMatchingName(); + findActorWithinGivenIdRange(); + findMoviesBetweenAPeriod(); + findMoviesGreaterThanLessThanYear(); + findMoviesUsingIdOrTitle(); + findMoviesUsingIdOrTitleOrYear(); + + } + + private void findAllActors() + { + Query query = em.createNativeQuery("ACTOR_ID:*", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(2, actors.size()); + } + + private void findActorByID() + { + Query query = em.createNativeQuery("ACTOR_ID:2", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor2(actors.get(0)); + } + + private void findActorByName() + { + Query query = em.createNativeQuery("ACTOR_NAME:\"Tom Cruise\"", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor1(actors.get(0)); + } + + private void findActorByIDAndName() + { + // Positive scenario + Query query = em.createNativeQuery("ACTOR_ID:1 AND ACTOR_NAME:\"Tom Cruise\"", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor1(actors.get(0)); + + // Negative scenario + query = em.createNativeQuery("ACTOR_ID:2 AND ACTOR_NAME:\"Tom Cruise\"", Actor.class); + actors = query.getResultList(); + Assert.assertTrue(actors == null || actors.isEmpty()); + } + + private void findActorWithMatchingName() + { + Query query = em.createNativeQuery("ACTOR_NAME:Emma*", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(1, actors.size()); + assertActor2(actors.get(0)); + } + + private void findActorWithinGivenIdRange() + { + // Records are inclusive of range boundaries + Query query = em.createNativeQuery("ACTOR_ID:[1 TO 2]", Actor.class); + List actors = query.getResultList(); + Assert.assertNotNull(actors); + Assert.assertFalse(actors.isEmpty()); + Assert.assertEquals(2, actors.size()); + } + + private void findMoviesBetweenAPeriod() + { + // Between + // Records are exclusive of range boundaries + Query query = em.createNativeQuery("YEAR:{1989 TO 2007}", Movie.class); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + + } + + private void findMoviesGreaterThanLessThanYear() + { + // Greater-than/ Less Than + Query query = em.createNativeQuery("YEAR:[2005 TO 2010]", Movie.class); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + } + + private void findMoviesUsingIdOrTitle() + { + Query query = em.createNativeQuery("MOVIE_ID:m1 OR TITLE:Miss*", Movie.class); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(2, movies.size()); + + for (Movie movie : movies) + { + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getId().equals("m1") || movie.getId().equals("m2")); + } + } + + private void findMoviesUsingIdOrTitleOrYear() + { + Query query = em.createNativeQuery("MOVIE_ID:m1 OR TITLE:Miss* OR YEAR:2009", Movie.class); + List movies = query.getResultList(); + Assert.assertNotNull(movies); + Assert.assertFalse(movies.isEmpty()); + Assert.assertEquals(3, movies.size()); + + for (Movie movie : movies) + { + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getId().equals("m1") || movie.getId().equals("m2") || movie.getId().equals("m3")); + } + } +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTestBase.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTestBase.java new file mode 100644 index 000000000..122045652 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTestBase.java @@ -0,0 +1,204 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.Assert; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Base class for All IMDB Tests + * + * @author amresh.singh + */ +public class IMDBTestBase +{ + protected Actor actor1; + + protected Actor actor2; + + protected static EntityManagerFactory emf; + + protected EntityManager em; + + protected static final String IMDB_PU = "imdb"; + + /** + * @param actor1 + * @param actor2 + */ + protected void assertActors(Actor actor1, Actor actor2) + { + assertActor1(actor1); + assertActor2(actor2); + } + + /** + * @param actor2 + */ + protected void assertActor2(Actor actor2) + { + Assert.assertNotNull(actor2); + Assert.assertEquals(2, actor2.getId()); + Assert.assertEquals("Emmanuelle Béart", actor2.getName()); + Map movies2 = actor2.getMovies(); + Assert.assertFalse(movies2 == null || movies2.isEmpty()); + Assert.assertEquals(2, movies2.size()); + for (Role role : movies2.keySet()) + { + Assert.assertNotNull(role); + Movie movie = movies2.get(role); + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getActors() != null && !movie.getActors().isEmpty()); + } + } + + /** + * @param actor1 + */ + protected void assertActor1(Actor actor1) + { + Assert.assertNotNull(actor1); + Assert.assertEquals(1, actor1.getId()); + Assert.assertEquals("Tom Cruise", actor1.getName()); + Map movies1 = actor1.getMovies(); + Assert.assertFalse(movies1 == null || movies1.isEmpty()); + Assert.assertEquals(2, movies1.size()); + for (Role role : movies1.keySet()) + { + Assert.assertNotNull(role); + Movie movie = movies1.get(role); + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getActors() != null && !movie.getActors().isEmpty()); + } + } + + /** + * @param actor1 + * @param actor2 + */ + protected void assertUpdatedActors(Actor actor1, Actor actor2) + { + assertUpdatedActor1(actor1); + assertUpdatedActor2(actor2); + } + + /** + * @param actor2 + */ + protected void assertUpdatedActor2(Actor actor2) + { + Assert.assertNotNull(actor2); + Assert.assertEquals(2, actor2.getId()); + Assert.assertEquals("Amir", actor2.getName()); + Map movies2 = actor2.getMovies(); + Assert.assertFalse(movies2 == null || movies2.isEmpty()); + Assert.assertEquals(2, movies2.size()); + for (Role role : movies2.keySet()) + { + Assert.assertNotNull(role); + Movie movie = movies2.get(role); + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getActors() != null && !movie.getActors().isEmpty()); + } + } + + /** + * @param actor1 + */ + protected void assertUpdatedActor1(Actor actor1) + { + Assert.assertNotNull(actor1); + Assert.assertEquals(1, actor1.getId()); + Assert.assertEquals("Amresh", actor1.getName()); + Map movies1 = actor1.getMovies(); + Assert.assertFalse(movies1 == null || movies1.isEmpty()); + Assert.assertEquals(2, movies1.size()); + for (Role role : movies1.keySet()) + { + Assert.assertNotNull(role); + Movie movie = movies1.get(role); + Assert.assertNotNull(movie); + Assert.assertTrue(movie.getActors() != null && !movie.getActors().isEmpty()); + } + } + + protected void populateActors() + { + // Actors + actor1 = new Actor(1, "Tom Cruise"); + actor2 = new Actor(2, "Emmanuelle Béart"); + + // Movies + Movie movie1 = new Movie("m1", "War of the Worlds", 2005); + Movie movie2 = new Movie("m2", "Mission Impossible", 1996); + Movie movie3 = new Movie("m3", "Hell", 2009); + + // Roles + Role role1 = new Role("Ray Ferrier", "Lead Actor"); + role1.setActor(actor1); + role1.setMovie(movie1); + Role role2 = new Role("Ethan Hunt", "Lead Actor"); + role2.setActor(actor1); + role2.setMovie(movie2); + Role role3 = new Role("Claire Phelps", "Lead Actress"); + role3.setActor(actor2); + role1.setMovie(movie2); + Role role4 = new Role("Sophie", "Supporting Actress"); + role4.setActor(actor2); + role1.setMovie(movie3); + + // Relationships + actor1.addMovie(role1, movie1); + actor1.addMovie(role2, movie2); + actor2.addMovie(role3, movie2); + actor2.addMovie(role4, movie3); + + movie1.addActor(role1, actor1); + movie2.addActor(role2, actor1); + movie2.addActor(role3, actor2); + movie3.addActor(role4, actor2); + } + + protected void init() + { + emf = Persistence.createEntityManagerFactory(IMDB_PU); + em = emf.createEntityManager(); + } + + protected void clean() throws IOException + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(IMDB_PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + emf.close(); + + if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath)); + } +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTransactionTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTransactionTest.java new file mode 100644 index 000000000..3bfb4c925 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/IMDBTransactionTest.java @@ -0,0 +1,212 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Test case for validating transaction handling provided by Kundera for Neo4J + * + * @author amresh.singh + */ +public class IMDBTransactionTest extends IMDBTestBase +{ + + + /* @BeforeClass + public static void setUpBeforeClass() throws Exception + { + @BeforeClass + public static void setUpBeforeClass() throws Exception + { + emf = Persistence.createEntityManagerFactory(IMDB_PU); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception + { + + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(IMDB_PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + FileUtils.deleteRecursively(new File(datastoreFilePath)); +// emf.close(); + }*/ + + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(IMDB_PU); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + +// em.close(); + clean(); + } + + @Test + public void withTransaction() + { + try + { + /** Prepare data */ + // Actors + populateActors(); + + /** Insert records */ + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + + /** Find records (Doesn't need transaction) */ + Actor actor11 = em.find(Actor.class, 1); + Actor actor22 = em.find(Actor.class, 2); + assertActors(actor11, actor22); + + /** Update records */ + em.clear(); + actor1.setName("Amresh"); + actor2.setName("Amir"); + em.getTransaction().begin(); + em.merge(actor1); + em.merge(actor2); + em.getTransaction().commit(); + em.clear(); + Actor actor1AfterMerge = em.find(Actor.class, 1); + Actor actor2AfterMerge = em.find(Actor.class, 2); + assertUpdatedActors(actor1AfterMerge, actor2AfterMerge); + + /** Delete records */ + em.clear(); + em.getTransaction().begin(); + em.remove(actor11); + em.getTransaction().commit(); + em.getTransaction().begin(); + em.remove(actor22); + em.getTransaction().commit(); + em.clear(); // clear cache + Actor actor1AfterDeletion = em.find(Actor.class, 1); + Actor actor2AfterDeletion = em.find(Actor.class, 2); + Assert.assertNull(actor1AfterDeletion); + Assert.assertNull(actor2AfterDeletion); + + } + catch (Exception e) + { + Assert.fail(e.getMessage()); + } + + } + + @Test + public void withoutTransaction() + { + /** Prepare data */ + populateActors(); + + /** Insert records without a transaction */ + try + { + em.persist(actor1); + em.persist(actor2); + Assert.fail(); + } + catch (Exception e) + { + Assert.assertTrue(e.getMessage().toString().indexOf("transaction") >= 0); + } + + /** Find records */ + em.clear(); + Actor actor11 = em.find(Actor.class, 1); + Actor actor22 = em.find(Actor.class, 2); + Assert.assertNull(actor11); + Assert.assertNull(actor22); + + } + + @Test + public void rollbackBehavior() + { + populateActors(); + + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().rollback(); + + em.clear(); + Actor actor11 = em.find(Actor.class, 1); + Actor actor22 = em.find(Actor.class, 2); + Assert.assertNull(actor11); + Assert.assertNull(actor22); + } + + @Test + public void rollbackBehaviorOnException() + { + populateActors(); + + try + { + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + + em.getTransaction().begin(); + actor1.setName("Amresh"); + actor2.setName("Amir"); + em.merge(actor1); + em.merge(actor2); + em.merge(null); + em.getTransaction().commit(); + } + catch (Exception e) + { + em.clear(); + Actor actor11 = em.find(Actor.class, 1); + Actor actor22 = em.find(Actor.class, 2); + Assert.assertNotNull(actor11); + Assert.assertNotNull(actor22); + Assert.assertNotSame("Amresh", actor11.getName()); + Assert.assertNotSame("Amir", actor22.getName()); + + } + + } +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Movie.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Movie.java new file mode 100644 index 000000000..cbe72f8ec --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Movie.java @@ -0,0 +1,141 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Movie Node entity class + * + * @author amresh.singh + */ + +@Entity +@Table +@IndexCollection(columns = { @Index(name = "title", type = "KEYS"), @Index(name = "year", type = "KEYS") }) +public class Movie +{ + @Id + @Column(name = "MOVIE_ID") + private String id; + + @Column(name = "TITLE") + private String title; + + @Column(name = "YEAR") + private int year; + + @ManyToMany(fetch = FetchType.LAZY, mappedBy = "movies") + private Map actors; + + public Movie() + { + } + + public Movie(String id, String title, int year) + { + this.id = id; + this.title = title; + this.year = year; + } + + public void addActor(Role role, Actor actor) + { + if (actors == null) + actors = new HashMap(); + actors.put(role, actor); + } + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the title + */ + public String getTitle() + { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the year + */ + public int getYear() + { + return year; + } + + /** + * @param year + * the year to set + */ + public void setYear(int year) + { + this.year = year; + } + + /** + * @return the actors + */ + public Map getActors() + { + return actors; + } + + /** + * @param actors + * the actors to set + */ + public void setActors(Map actors) + { + this.actors = actors; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Role.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Role.java new file mode 100644 index 000000000..57baa4339 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/Role.java @@ -0,0 +1,149 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Role Relationship entity class + * + * @author amresh.singh + */ +@Entity +@Table +@IndexCollection(columns = { @Index(name = "roleType", type = "KEYS") }) +public class Role +{ + @Id + @Column(name = "ROLE_NAME") + private String roleName; + + @Column(name = "ROLE_TYPE") + private String roleType; + + @OneToOne + private Actor actor; + + @OneToOne + private Movie movie; + + public Role() + { + } + + public Role(String roleName, String roleType) + { + this.roleName = roleName; + this.roleType = roleType; + } + + /** + * @return the roleName + */ + public String getRoleName() + { + return roleName; + } + + /** + * @param roleName + * the roleName to set + */ + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + /** + * @return the roleType + */ + public String getRoleType() + { + return roleType; + } + + /** + * @param roleType + * the roleType to set + */ + public void setRoleType(String roleType) + { + this.roleType = roleType; + } + + /** + * @return the actor + */ + public Actor getActor() + { + return actor; + } + + /** + * @param actor + * the actor to set + */ + public void setActor(Actor actor) + { + this.actor = actor; + } + + /** + * @return the movie + */ + public Movie getMovie() + { + return movie; + } + + /** + * @param movie + * the movie to set + */ + public void setMovie(Movie movie) + { + this.movie = movie; + } + + public boolean equals(Object o) + { + if (!(o instanceof Role)) + { + return false; + } + + Role that = (Role) o; + + return (this.roleName == that.roleName || this.roleName.equals(that.roleName)) + && (this.roleType == that.roleType || this.roleType.equals(that.roleType)); + + } + + public int hashCode() + { + int h1 = (roleName == null) ? 0 : roleName.hashCode(); + int h2 = (roleType == null) ? 0 : roleType.hashCode(); + return h1 + 31 * h2; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorComposite.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorComposite.java new file mode 100644 index 000000000..a4179ddbb --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorComposite.java @@ -0,0 +1,123 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ManyToMany; +import javax.persistence.MapKeyJoinColumn; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Actor Node Entity class + * + * @author amresh.singh + */ + +@Entity +@Table +// Ignored for Neo4J +@IndexCollection(columns = { @Index(name = "name", type = "KEYS") }) +public class ActorComposite +{ + @EmbeddedId + private ActorId actorId; + + @Column(name = "ACTOR_NAME") + private String name; + + public ActorComposite() + { + } + + public ActorComposite(ActorId actorId, String actorName) + { + this.actorId = actorId; + this.name = actorName; + } + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @MapKeyJoinColumn(name = "ACTS_IN") + private Map movies; + + public void addMovie(RoleComposite role, MovieComposite movie) + { + if (movies == null) + movies = new HashMap(); + movies.put(role, movie); + } + + /** + * @return the actorId + */ + public ActorId getActorId() + { + return actorId; + } + + /** + * @param actorId + * the actorId to set + */ + public void setActorId(ActorId actorId) + { + this.actorId = actorId; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the movies + */ + public Map getMovies() + { + return movies; + } + + /** + * @param movies + * the movies to set + */ + public void setMovies(Map movies) + { + this.movies = movies; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorId.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorId.java new file mode 100644 index 000000000..8cda8e25c --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/ActorId.java @@ -0,0 +1,84 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * Class Holding Identity attributes for actors + * + * @author amresh.singh + */ +@Embeddable +public class ActorId +{ + @Column(name = "ACTOR_ID_PREFIX") + private String prefix; + + @Column(name = "ACTOR_ID_SUFFIX") + private int suffix; + + public ActorId() + { + } + + /** + * @param prefix + * @param suffix + */ + public ActorId(String prefix, int suffix) + { + super(); + this.prefix = prefix; + this.suffix = suffix; + } + + /** + * @return the prefix + */ + public String getPrefix() + { + return prefix; + } + + /** + * @param prefix + * the prefix to set + */ + public void setPrefix(String prefix) + { + this.prefix = prefix; + } + + /** + * @return the suffix + */ + public int getSuffix() + { + return suffix; + } + + /** + * @param suffix + * the suffix to set + */ + public void setSuffix(int suffix) + { + this.suffix = suffix; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/IMDBCompositeKeyTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/IMDBCompositeKeyTest.java new file mode 100644 index 000000000..00ee7b399 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/IMDBCompositeKeyTest.java @@ -0,0 +1,229 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import java.io.File; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.KunderaMetadata; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Test case for entities that hold composite keys + * + * @author amresh.singh + */ +public class IMDBCompositeKeyTest +{ + + EntityManagerFactory emf; + + EntityManager em; + + private static final String IMDB_PU = "imdb"; + + ActorComposite actor1; + + ActorComposite actor2; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + KunderaMetadata.INSTANCE.setApplicationMetadata(null); + emf = Persistence.createEntityManagerFactory(IMDB_PU); + em = emf.createEntityManager(); + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(IMDB_PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + emf.close(); + + /*if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath));*/ + + } + + @Test + public void testCompositeKeys() + { + insert(); + findById(); + merge(); + delete(); + } + + /** + * + */ + public void insert() + { + prepareData(); + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + } + + private void findById() + { + // Find actor by ID + em.clear(); + ActorComposite actor1 = em.find(ActorComposite.class, new ActorId("A", 1)); + ActorComposite actor2 = em.find(ActorComposite.class, new ActorId("A", 2)); + + assertActors(actor1, actor2); + } + + private void merge() + { + em.clear(); + ActorComposite actor1 = em.find(ActorComposite.class, new ActorId("A", 1)); + ActorComposite actor2 = em.find(ActorComposite.class, new ActorId("A", 2)); + assertActors(actor1, actor2); + + actor1.setName("Amresh"); + actor2.setName("Amir"); + + em.getTransaction().begin(); + em.merge(actor1); + em.merge(actor2); + em.getTransaction().commit(); + + em.clear(); + + ActorComposite actor1AfterMerge = em.find(ActorComposite.class, new ActorId("A", 1)); + ActorComposite actor2AfterMerge = em.find(ActorComposite.class, new ActorId("A", 2)); + + assertUpdatedActors(actor1AfterMerge, actor2AfterMerge); + } + + private void delete() + { + em.clear(); + ActorComposite actor1 = em.find(ActorComposite.class, new ActorId("A", 1)); + ActorComposite actor2 = em.find(ActorComposite.class, new ActorId("A", 2)); + + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + + em.clear(); + ActorComposite actor1AfterDeletion = em.find(ActorComposite.class, new ActorId("A", 1)); + ActorComposite actor2AfterDeletion = em.find(ActorComposite.class, new ActorId("A", 2)); + Assert.assertNull(actor1AfterDeletion); + Assert.assertNull(actor2AfterDeletion); + } + + private void prepareData() + { + // Actors + actor1 = new ActorComposite(new ActorId("A", 1), "Tom Cruise"); + actor2 = new ActorComposite(new ActorId("A", 2), "Emmanuelle Béart"); + + // Movies + MovieComposite movie1 = new MovieComposite(new MovieId('U', 11111111L), "War of the Worlds", 2005); + MovieComposite movie2 = new MovieComposite(new MovieId('U', 22222222L), "Mission Impossible", 1996); + MovieComposite movie3 = new MovieComposite(new MovieId('A', 33333333L), "Hell", 2005); + + // Roles + RoleComposite role1 = new RoleComposite(new RoleId("Ray", "Ferrier"), "Lead Actor"); + role1.setActor(actor1); + role1.setMovie(movie1); + RoleComposite role2 = new RoleComposite(new RoleId("Ethan", "Hunt"), "Lead Actor"); + role2.setActor(actor1); + role2.setMovie(movie2); + RoleComposite role3 = new RoleComposite(new RoleId("Claire", "Phelps"), "Lead Actress"); + role3.setActor(actor2); + role1.setMovie(movie2); + RoleComposite role4 = new RoleComposite(new RoleId("Sophie", ""), "Supporting Actress"); + role4.setActor(actor2); + role1.setMovie(movie3); + + // Relationships + actor1.addMovie(role1, movie1); + actor1.addMovie(role2, movie2); + actor2.addMovie(role3, movie2); + actor2.addMovie(role4, movie3); + + movie1.addActor(role1, actor1); + movie2.addActor(role2, actor1); + movie2.addActor(role3, actor2); + movie3.addActor(role4, actor2); + } + + private void assertActors(ActorComposite actor1, ActorComposite actor2) + { + Assert.assertNotNull(actor1); + Assert.assertEquals("A", actor1.getActorId().getPrefix()); + Assert.assertEquals(1, actor1.getActorId().getSuffix()); + Assert.assertEquals("Tom Cruise", actor1.getName()); + Map movies1 = actor1.getMovies(); + Assert.assertFalse(movies1 == null || movies1.isEmpty()); + Assert.assertEquals(2, movies1.size()); + + Assert.assertNotNull(actor2); + Assert.assertEquals("A", actor2.getActorId().getPrefix()); + Assert.assertEquals(2, actor2.getActorId().getSuffix()); + Assert.assertEquals("Emmanuelle Béart", actor2.getName()); + Map movies2 = actor2.getMovies(); + Assert.assertFalse(movies2 == null || movies2.isEmpty()); + Assert.assertEquals(2, movies2.size()); + } + + private void assertUpdatedActors(ActorComposite actor1, ActorComposite actor2) + { + Assert.assertNotNull(actor1); + Assert.assertEquals("A", actor1.getActorId().getPrefix()); + Assert.assertEquals(1, actor1.getActorId().getSuffix()); + Assert.assertEquals("Amresh", actor1.getName()); + Map movies1 = actor1.getMovies(); + Assert.assertFalse(movies1 == null || movies1.isEmpty()); + Assert.assertEquals(2, movies1.size()); + + Assert.assertNotNull(actor2); + Assert.assertEquals("A", actor2.getActorId().getPrefix()); + Assert.assertEquals(2, actor2.getActorId().getSuffix()); + Assert.assertEquals("Amir", actor2.getName()); + Map movies2 = actor2.getMovies(); + Assert.assertFalse(movies2 == null || movies2.isEmpty()); + Assert.assertEquals(2, movies2.size()); + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieComposite.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieComposite.java new file mode 100644 index 000000000..4b9c4f574 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieComposite.java @@ -0,0 +1,140 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Movie Node entity class + * + * @author amresh.singh + */ + +@Entity +@Table +@IndexCollection(columns = { @Index(name = "title", type = "KEYS"), @Index(name = "year", type = "KEYS") }) +public class MovieComposite +{ + @EmbeddedId + private MovieId movieId; + + @Column(name = "TITLE") + private String title; + + @Column(name = "YEAR") + private int year; + + @ManyToMany(fetch = FetchType.LAZY, mappedBy = "movies") + private Map actors; + + public MovieComposite() + { + } + + public MovieComposite(MovieId id, String title, int year) + { + this.movieId = id; + this.title = title; + this.year = year; + } + + public void addActor(RoleComposite role, ActorComposite actor) + { + if (actors == null) + actors = new HashMap(); + actors.put(role, actor); + } + + /** + * @return the movieId + */ + public MovieId getMovieId() + { + return movieId; + } + + /** + * @param movieId + * the movieId to set + */ + public void setMovieId(MovieId movieId) + { + this.movieId = movieId; + } + + /** + * @return the title + */ + public String getTitle() + { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the year + */ + public int getYear() + { + return year; + } + + /** + * @param year + * the year to set + */ + public void setYear(int year) + { + this.year = year; + } + + /** + * @return the actors + */ + public Map getActors() + { + return actors; + } + + /** + * @param actors + * the actors to set + */ + public void setActors(Map actors) + { + this.actors = actors; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieId.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieId.java new file mode 100644 index 000000000..2a35ea118 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/MovieId.java @@ -0,0 +1,84 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * Class Holding Identity attributes for movies + * + * @author amresh.singh + */ +@Embeddable +public class MovieId +{ + @Column(name = "CERTIFICATION") + private char certification; + + @Column(name = "SERIAL_NUMBER") + private long serialNumber; + + public MovieId() + { + } + + /** + * @param certification + * @param serialNumber + */ + public MovieId(char certification, long serialNumber) + { + super(); + this.certification = certification; + this.serialNumber = serialNumber; + } + + /** + * @return the certification + */ + public char getCertification() + { + return certification; + } + + /** + * @param certification + * the certification to set + */ + public void setCertification(char certification) + { + this.certification = certification; + } + + /** + * @return the serialNumber + */ + public long getSerialNumber() + { + return serialNumber; + } + + /** + * @param serialNumber + * the serialNumber to set + */ + public void setSerialNumber(long serialNumber) + { + this.serialNumber = serialNumber; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleComposite.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleComposite.java new file mode 100644 index 000000000..7d35c3b21 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleComposite.java @@ -0,0 +1,148 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import javax.persistence.Column; +import javax.persistence.EmbeddedId; +import javax.persistence.Entity; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Role Relationship entity class + * + * @author amresh.singh + */ +@Entity +@Table +@IndexCollection(columns = { @Index(name = "roleType", type = "KEYS") }) +public class RoleComposite +{ + @EmbeddedId + private RoleId roleId; + + @Column(name = "ROLE_TYPE") + private String roleType; + + @OneToOne + private ActorComposite actor; + + @OneToOne + private MovieComposite movie; + + public RoleComposite() + { + } + + public RoleComposite(RoleId id, String roleType) + { + this.roleId = id; + this.roleType = roleType; + } + + /** + * @return the roleId + */ + public RoleId getRoleId() + { + return roleId; + } + + /** + * @param roleId + * the roleId to set + */ + public void setRoleId(RoleId roleId) + { + this.roleId = roleId; + } + + /** + * @return the roleType + */ + public String getRoleType() + { + return roleType; + } + + /** + * @param roleType + * the roleType to set + */ + public void setRoleType(String roleType) + { + this.roleType = roleType; + } + + /** + * @return the actor + */ + public ActorComposite getActor() + { + return actor; + } + + /** + * @param actor + * the actor to set + */ + public void setActor(ActorComposite actor) + { + this.actor = actor; + } + + /** + * @return the movie + */ + public MovieComposite getMovie() + { + return movie; + } + + /** + * @param movie + * the movie to set + */ + public void setMovie(MovieComposite movie) + { + this.movie = movie; + } + + public boolean equals(Object o) + { + if (!(o instanceof RoleComposite)) + { + return false; + } + + RoleComposite that = (RoleComposite) o; + + return (this.roleId == that.roleId || this.roleId.equals(that.roleId)) + && (this.roleType == that.roleType || this.roleType.equals(that.roleType)); + + } + + public int hashCode() + { + int h1 = (roleId == null) ? 0 : roleId.hashCode(); + int h2 = (roleType == null) ? 0 : roleType.hashCode(); + return h1 + 31 * h2; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleId.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleId.java new file mode 100644 index 000000000..c6f1831f7 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/composite/RoleId.java @@ -0,0 +1,104 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.composite; + +import javax.persistence.Column; +import javax.persistence.Embeddable; + +/** + * Class Holding Identity attributes for roles + * + * @author amresh.singh + */ +@Embeddable +public class RoleId +{ + @Column(name = "FIRST_NAME") + private String firstName; + + @Column(name = "LAST_NAME") + private String lastName; + + public RoleId() + { + } + + /** + * @param firstName + * @param lastName + */ + public RoleId(String firstName, String lastName) + { + super(); + this.firstName = firstName; + this.lastName = lastName; + } + + /** + * @return the firstName + */ + public String getFirstName() + { + return firstName; + } + + /** + * @param firstName + * the firstName to set + */ + public void setFirstName(String firstName) + { + this.firstName = firstName; + } + + /** + * @return the lastName + */ + public String getLastName() + { + return lastName; + } + + /** + * @param lastName + * the lastName to set + */ + public void setLastName(String lastName) + { + this.lastName = lastName; + } + + public boolean equals(Object o) + { + if (!(o instanceof RoleId)) + { + return false; + } + + RoleId that = (RoleId) o; + + return (this.firstName == that.firstName || this.firstName.equals(that.firstName)) + && (this.lastName == that.lastName || this.lastName.equals(that.lastName)); + } + + public int hashCode() + { + int h1 = (firstName == null) ? 0 : firstName.hashCode(); + int h2 = (lastName == null) ? 0 : lastName.hashCode(); + return h1 + 31 * h2; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/ActorAllDataType.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/ActorAllDataType.java new file mode 100644 index 000000000..ae3d1ee67 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/ActorAllDataType.java @@ -0,0 +1,475 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.datatype; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.MapKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Entity Class for Actor + * + * @author amresh.singh + */ +@Entity +@Table +// Ignored for Neo4J +@IndexCollection(columns = { @Index(name = "name", type = "KEYS") }) +public class ActorAllDataType +{ + @Id + @Column(name = "ACTOR_ID") + private int id; + + @Column(name = "ACTOR_NAME") + private String name; + + @Column(name = "DEPARTMENT_ID") + private long departmentId; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "GRADE") + private char grade; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "RATING") + private short rating; // 1-10 + + @Column(name = "COMPLIANCE") + private float compliance; + + @Column(name = "HEIGHT") + private double height; + + // Date-time types + @Column(name = "ENROLMENT_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date enrolmentDate; + + @Column(name = "ENROLMENT_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date enrolmentTime; + + @Column(name = "JOINING_DATE_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date joiningDateAndTime; + + // Wrapper types + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "UNIQUE_ID") + private Long uniqueId; + + @Column(name = "MONTHLY_SALARY") + private Double monthlySalary; + + @Column(name = "JOB_ATTEMPTS") + private BigInteger jobAttempts; + + @Column(name = "ACCUMULATED_WEALTH") + private BigDecimal accumulatedWealth; + + @Column(name = "GRADUATION_DAY") + private Calendar graduationDay; + + public ActorAllDataType() + { + } + + public ActorAllDataType(int id, String name, long departmentId, boolean isExceptional, char grade, + byte digitalSignature, short rating, float compliance, double height, Date enrolmentDate, + Date enrolmentTime, Date joiningDateAndTime, Integer yearsSpent, Long uniqueId, Double monthlySalary, + BigInteger jobAttempts, BigDecimal accumulatedWealth, Calendar graduationDay) + { + + super(); + this.id = id; + this.name = name; + this.departmentId = departmentId; + this.isExceptional = isExceptional; + this.grade = grade; + this.digitalSignature = digitalSignature; + this.rating = rating; + this.compliance = compliance; + this.height = height; + this.enrolmentDate = enrolmentDate; + this.enrolmentTime = enrolmentTime; + this.joiningDateAndTime = joiningDateAndTime; + this.yearsSpent = yearsSpent; + this.uniqueId = uniqueId; + this.monthlySalary = monthlySalary; + this.jobAttempts = jobAttempts; + this.accumulatedWealth = accumulatedWealth; + this.graduationDay = graduationDay; + } + + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @MapKeyJoinColumn(name = "ACTS_IN") + private Map movies; + + public void addMovie(RoleAllDataType role, MovieAllDataType movie) + { + if (movies == null) + movies = new HashMap(); + movies.put(role, movie); + } + + /** + * @return the id + */ + public int getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(int id) + { + this.id = id; + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the departmentId + */ + public long getDepartmentId() + { + return departmentId; + } + + /** + * @param departmentId + * the departmentId to set + */ + public void setDepartmentId(long departmentId) + { + this.departmentId = departmentId; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the grade + */ + public char getGrade() + { + return grade; + } + + /** + * @param grade + * the grade to set + */ + public void setGrade(char grade) + { + this.grade = grade; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the rating + */ + public short getRating() + { + return rating; + } + + /** + * @param rating + * the rating to set + */ + public void setRating(short rating) + { + this.rating = rating; + } + + /** + * @return the compliance + */ + public float getCompliance() + { + return compliance; + } + + /** + * @param compliance + * the compliance to set + */ + public void setCompliance(float compliance) + { + this.compliance = compliance; + } + + /** + * @return the height + */ + public double getHeight() + { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(double height) + { + this.height = height; + } + + /** + * @return the enrolmentDate + */ + public java.util.Date getEnrolmentDate() + { + return enrolmentDate; + } + + /** + * @param enrolmentDate + * the enrolmentDate to set + */ + public void setEnrolmentDate(java.util.Date enrolmentDate) + { + this.enrolmentDate = enrolmentDate; + } + + /** + * @return the enrolmentTime + */ + public java.util.Date getEnrolmentTime() + { + return enrolmentTime; + } + + /** + * @param enrolmentTime + * the enrolmentTime to set + */ + public void setEnrolmentTime(java.util.Date enrolmentTime) + { + this.enrolmentTime = enrolmentTime; + } + + /** + * @return the joiningDateAndTime + */ + public java.util.Date getJoiningDateAndTime() + { + return joiningDateAndTime; + } + + /** + * @param joiningDateAndTime + * the joiningDateAndTime to set + */ + public void setJoiningDateAndTime(java.util.Date joiningDateAndTime) + { + this.joiningDateAndTime = joiningDateAndTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the uniqueId + */ + public Long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(Long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the monthlySalary + */ + public Double getMonthlySalary() + { + return monthlySalary; + } + + /** + * @param monthlySalary + * the monthlySalary to set + */ + public void setMonthlySalary(Double monthlySalary) + { + this.monthlySalary = monthlySalary; + } + + /** + * @return the jobAttempts + */ + public BigInteger getJobAttempts() + { + return jobAttempts; + } + + /** + * @param jobAttempts + * the jobAttempts to set + */ + public void setJobAttempts(BigInteger jobAttempts) + { + this.jobAttempts = jobAttempts; + } + + /** + * @return the accumulatedWealth + */ + public BigDecimal getAccumulatedWealth() + { + return accumulatedWealth; + } + + /** + * @param accumulatedWealth + * the accumulatedWealth to set + */ + public void setAccumulatedWealth(BigDecimal accumulatedWealth) + { + this.accumulatedWealth = accumulatedWealth; + } + + /** + * @return the graduationDay + */ + public Calendar getGraduationDay() + { + return graduationDay; + } + + /** + * @param graduationDay + * the graduationDay to set + */ + public void setGraduationDay(Calendar graduationDay) + { + this.graduationDay = graduationDay; + } + + /** + * @return the movies + */ + public Map getMovies() + { + return movies; + } + + /** + * @param movies + * the movies to set + */ + public void setMovies(Map movies) + { + this.movies = movies; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/IMDBAllDataTypeTest.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/IMDBAllDataTypeTest.java new file mode 100644 index 000000000..250a8ab64 --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/IMDBAllDataTypeTest.java @@ -0,0 +1,290 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.datatype; + +import java.io.File; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.neo4j.kernel.impl.util.FileUtils; + +import com.impetus.kundera.PersistenceProperties; +import com.impetus.kundera.metadata.KunderaMetadataManager; +import com.impetus.kundera.metadata.model.PersistenceUnitMetadata; + +/** + * Test case + * + * @author amresh.singh + */ +public class IMDBAllDataTypeTest +{ + EntityManagerFactory emf; + + EntityManager em; + + Calendar cal = Calendar.getInstance(); + + ActorAllDataType actor1; + + ActorAllDataType actor2; + + private static final String IMDB_PU = "imdb"; + + /** + * @throws java.lang.Exception + */ + @Before + public void setUp() throws Exception + { + emf = Persistence.createEntityManagerFactory(IMDB_PU); + em = emf.createEntityManager(); + + } + + /** + * @throws java.lang.Exception + */ + @After + public void tearDown() throws Exception + { + // Delete inserted records + ActorAllDataType actor1 = em.find(ActorAllDataType.class, 1); + ActorAllDataType actor2 = em.find(ActorAllDataType.class, 2); + + if (actor1 != null && actor2 != null) + { + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + } + + MovieAllDataType movie1 = em.find(MovieAllDataType.class, "m1"); + MovieAllDataType movie2 = em.find(MovieAllDataType.class, "m2"); + MovieAllDataType movie3 = em.find(MovieAllDataType.class, "m3"); + + if (movie1 != null) + { + em.getTransaction().begin(); + em.remove(movie1); + em.getTransaction().commit(); + } + + if (movie2 != null) + { + em.getTransaction().begin(); + em.remove(movie2); + em.getTransaction().commit(); + } + + if (movie3 != null) + { + em.getTransaction().begin(); + em.remove(movie3); + em.getTransaction().commit(); + } + + PersistenceUnitMetadata puMetadata = KunderaMetadataManager.getPersistenceUnitMetadata(IMDB_PU); + String datastoreFilePath = puMetadata.getProperty(PersistenceProperties.KUNDERA_DATASTORE_FILE_PATH); + + em.close(); + emf.close(); + if (datastoreFilePath != null) + FileUtils.deleteRecursively(new File(datastoreFilePath)); + + } + + @Test + public void testCRUD() + { + insert(); + findById(); + delete(); + } + + private void insert() + { + prepareData(); + + em.getTransaction().begin(); + em.persist(actor1); + em.persist(actor2); + em.getTransaction().commit(); + } + + private void findById() + { + // Find actor by ID + em.clear(); + ActorAllDataType actor1 = em.find(ActorAllDataType.class, 1); + ActorAllDataType actor2 = em.find(ActorAllDataType.class, 2); + + assertActors(actor1, actor2); + } + + private void delete() + { + ActorAllDataType actor1 = em.find(ActorAllDataType.class, 1); + ActorAllDataType actor2 = em.find(ActorAllDataType.class, 2); + + em.getTransaction().begin(); + em.remove(actor1); + em.remove(actor2); + em.getTransaction().commit(); + + em.clear(); + ActorAllDataType actor11 = em.find(ActorAllDataType.class, 1); + ActorAllDataType actor22 = em.find(ActorAllDataType.class, 2); + Assert.assertNull(actor11); + Assert.assertNull(actor22); + } + + private void assertActors(ActorAllDataType actor1, ActorAllDataType actor2) + { + Assert.assertNotNull(actor1); + Assert.assertEquals(1, actor1.getId()); + Assert.assertEquals("Tom Cruise", actor1.getName()); + Assert.assertEquals(23456789l, actor1.getDepartmentId()); + Assert.assertEquals(true, actor1.isExceptional()); + Assert.assertEquals('C', actor1.getGrade()); + Assert.assertEquals((byte) 8, actor1.getDigitalSignature()); + Assert.assertEquals((short) 5, actor1.getRating()); + Assert.assertEquals((float) 10.0, actor1.getCompliance(), 0.0); + Assert.assertEquals(163.12, actor1.getHeight(), 0.0); + Assert.assertEquals(new Date(Long.parseLong("1351667541111")), actor1.getEnrolmentDate()); + Assert.assertEquals(new Date(Long.parseLong("1351667542222")), actor1.getEnrolmentTime()); + Assert.assertEquals(new Date(Long.parseLong("1351667543333")), actor1.getJoiningDateAndTime()); + Assert.assertEquals(new Integer(2), actor1.getYearsSpent()); + Assert.assertEquals(new Long(3634521523423L), actor1.getUniqueId()); + Assert.assertEquals(new Double(7.23452342343), actor1.getMonthlySalary()); + Assert.assertEquals(new BigInteger("123456789"), actor1.getJobAttempts()); + Assert.assertEquals(new BigDecimal(123456789), actor1.getAccumulatedWealth()); + Assert.assertEquals(cal, actor1.getGraduationDay()); + + Map movies1 = actor1.getMovies(); + Assert.assertFalse(movies1 == null || movies1.isEmpty()); + Assert.assertEquals(2, movies1.size()); + for (RoleAllDataType role : movies1.keySet()) + { + Assert.assertNotNull(role); + Assert.assertNotNull(role.getActor()); + Assert.assertNotNull(role.getMovie()); + Assert.assertNotNull(movies1.get(role)); + } + + Assert.assertNotNull(actor2); + Assert.assertEquals(2, actor2.getId()); + Assert.assertEquals("Emmanuelle Béart", actor2.getName()); + Assert.assertEquals(23456790l, actor2.getDepartmentId()); + Assert.assertEquals(false, actor2.isExceptional()); + Assert.assertEquals('D', actor2.getGrade()); + Assert.assertEquals((byte) 9, actor2.getDigitalSignature()); + Assert.assertEquals((short) 6, actor2.getRating()); + Assert.assertEquals((float) 11.3, actor2.getCompliance(), 0.0); + Assert.assertEquals(161.99, actor2.getHeight(), 0.0); + Assert.assertEquals(new Date(Long.parseLong("1351667544444")), actor2.getEnrolmentDate()); + Assert.assertEquals(new Date(Long.parseLong("1351667545555")), actor2.getEnrolmentTime()); + Assert.assertEquals(new Date(Long.parseLong("1351667546666")), actor2.getJoiningDateAndTime()); + Assert.assertEquals(new Integer(3), actor2.getYearsSpent()); + Assert.assertEquals(new Long(3634521523453L), actor2.getUniqueId()); + Assert.assertEquals(new Double(8.23452342343), actor2.getMonthlySalary()); + Assert.assertEquals(new BigInteger("123456790"), actor2.getJobAttempts()); + Assert.assertEquals(new BigDecimal(123456790), actor2.getAccumulatedWealth()); + Assert.assertEquals(cal, actor2.getGraduationDay()); + + Map movies2 = actor2.getMovies(); + Assert.assertFalse(movies2 == null || movies2.isEmpty()); + Assert.assertEquals(2, movies2.size()); + + for (RoleAllDataType role : movies2.keySet()) + { + Assert.assertNotNull(role); + Assert.assertNotNull(role.getActor()); + Assert.assertNotNull(role.getMovie()); + Assert.assertNotNull(movies2.get(role)); + } + } + + private void prepareData() + { + actor1 = new ActorAllDataType(1, "Tom Cruise", 23456789l, true, 'C', (byte) 8, (short) 5, (float) 10.0, 163.12, + new Date(Long.parseLong("1351667541111")), new Date(Long.parseLong("1351667542222")), new Date( + Long.parseLong("1351667543333")), 2, new Long(3634521523423L), new Double(7.23452342343), + new BigInteger("123456789"), new BigDecimal(123456789), cal); + + actor2 = new ActorAllDataType(2, "Emmanuelle Béart", 23456790l, false, 'D', (byte) 9, (short) 6, (float) 11.3, + 161.99, new Date(Long.parseLong("1351667544444")), new Date(Long.parseLong("1351667545555")), new Date( + Long.parseLong("1351667546666")), 3, new Long(3634521523453L), new Double(8.23452342343), + new BigInteger("123456790"), new BigDecimal(123456790), cal); + + // Movies + MovieAllDataType movie1 = new MovieAllDataType("m1", "War of the Worlds", 2005); + MovieAllDataType movie2 = new MovieAllDataType("m2", "Mission Impossible", 1996); + MovieAllDataType movie3 = new MovieAllDataType("m3", "Hell", 2005); + + // Roles + RoleAllDataType role1 = new RoleAllDataType("Ray Ferrier", "Lead Actor", 1, 354354354l, true, 'A', (byte) 8, + (short) 5, 3.7f, 6.5, new Date(Long.parseLong("1351667541111")), new Date( + Long.parseLong("1351667542222")), new Date(Long.parseLong("1351667543333")), 1, 98682342343l, + 6.7, new BigInteger("1111111111111"), new BigDecimal(1234567890), cal); + role1.setActor(actor1); + role1.setMovie(movie1); + + RoleAllDataType role2 = new RoleAllDataType("Ethan Hunt", "Lead Actor", 2, 354354355l, false, 'B', (byte) 9, + (short) 6, 3.8f, 6.8, new Date(Long.parseLong("1351667544444")), new Date( + Long.parseLong("1351667545555")), new Date(Long.parseLong("1351667546666")), 2, 98682342344l, + 6.8, new BigInteger("22222222222222"), new BigDecimal(1234567891), cal); + role2.setActor(actor1); + role2.setMovie(movie2); + + RoleAllDataType role3 = new RoleAllDataType("Claire Phelps", "Lead Actress", 3, 354354356l, true, 'C', + (byte) 10, (short) 7, 3.9f, 6.9, new Date(Long.parseLong("1351667547777")), new Date( + Long.parseLong("1351667548888")), new Date(Long.parseLong("1351667549999")), 3, 98682342345l, + 6.9, new BigInteger("3333333333333"), new BigDecimal(1234567892), cal); + role3.setActor(actor2); + role1.setMovie(movie2); + + RoleAllDataType role4 = new RoleAllDataType("Sophie", "Supporting Actress", 4, 354354357l, false, 'D', + (byte) 11, (short) 5, 3.7f, 7.0, new Date(Long.parseLong("1351667551111")), new Date( + Long.parseLong("1351667552222")), new Date(Long.parseLong("1351667553333")), 4, 98682342346l, + 7.0, new BigInteger("4444444444444"), new BigDecimal(1234567893), cal); + role4.setActor(actor2); + role1.setMovie(movie3); + + // Relationships + actor1.addMovie(role1, movie1); + actor1.addMovie(role2, movie2); + actor2.addMovie(role3, movie2); + actor2.addMovie(role4, movie3); + + movie1.addActor(role1, actor1); + movie2.addActor(role2, actor1); + movie2.addActor(role3, actor2); + movie3.addActor(role4, actor2); + } +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/MovieAllDataType.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/MovieAllDataType.java new file mode 100644 index 000000000..5b81cf77a --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/MovieAllDataType.java @@ -0,0 +1,141 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.datatype; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Id; +import javax.persistence.ManyToMany; +import javax.persistence.Table; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Movie entity containing all data type fields + * + * @author amresh.singh + */ +@Entity +@Table +@IndexCollection(columns = { @Index(name = "title", type = "KEYS"), @Index(name = "year", type = "KEYS") }) +public class MovieAllDataType +{ + @Id + @Column(name = "MOVIE_ID") + private String id; + + @Column(name = "TITLE") + private String title; + + @Column(name = "YEAR") + private int year; + + @ManyToMany(fetch = FetchType.LAZY, mappedBy = "movies") + private Map actors; + + public MovieAllDataType() + { + } + + public MovieAllDataType(String id, String title, int year) + { + super(); + this.id = id; + this.title = title; + this.year = year; + } + + public void addActor(RoleAllDataType role, ActorAllDataType actor) + { + if (actors == null) + actors = new HashMap(); + actors.put(role, actor); + } + + /** + * @return the id + */ + public String getId() + { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(String id) + { + this.id = id; + } + + /** + * @return the title + */ + public String getTitle() + { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return the year + */ + public int getYear() + { + return year; + } + + /** + * @param year + * the year to set + */ + public void setYear(int year) + { + this.year = year; + } + + /** + * @return the actors + */ + public Map getActors() + { + return actors; + } + + /** + * @param actors + * the actors to set + */ + public void setActors(Map actors) + { + this.actors = actors; + } + +} diff --git a/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/RoleAllDataType.java b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/RoleAllDataType.java new file mode 100644 index 000000000..c1a7b953d --- /dev/null +++ b/src/kundera-neo4j/src/test/java/com/impetus/client/neo4j/imdb/datatype/RoleAllDataType.java @@ -0,0 +1,502 @@ +/** + * Copyright 2012 Impetus Infotech. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.impetus.client.neo4j.imdb.datatype; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.impetus.kundera.index.Index; +import com.impetus.kundera.index.IndexCollection; + +/** + * Role Entity containing all data types + * + * @author amresh.singh + */ +@Entity +@Table +@IndexCollection(columns = { @Index(name = "roleType", type = "KEYS") }) +public class RoleAllDataType +{ + @Id + @Column(name = "ROLE_NAME") + private String roleName; + + @Column(name = "ROLE_TYPE") + private String roleType; + + @Column(name = "ROLE_CODE") + private int roleCode; + + @Column(name = "ROLE_LOCATION_ID") + private long roleLocationId; + + @Column(name = "IS_EXCEPTIONAL") + private boolean isExceptional; + + @Column(name = "GRADE") + private char grade; // A,B,C,D,E,F for i to vi + + @Column(name = "DIGITAL_SIGNATURE") + private byte digitalSignature; + + @Column(name = "RATING") + private short rating; // 1-10 + + @Column(name = "COMPLIANCE") + private float compliance; + + @Column(name = "IMDB_RATING") + private double imdbRating; + + // Date-time types + @Column(name = "ROLE_START_DATE") + @Temporal(TemporalType.DATE) + private java.util.Date roleStartDate; + + @Column(name = "ROLE_START_TIME") + @Temporal(TemporalType.TIME) + private java.util.Date roleStartTime; + + @Column(name = "SCRIPT_READ_TIME") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date scriptReadTime; + + // Wrapper types + @Column(name = "YEARS_SPENT") + private Integer yearsSpent; + + @Column(name = "UNIQUE_ID") + private Long uniqueId; + + @Column(name = "REMUNERATION") + private Double remuneration; + + @Column(name = "REHEARSAL_ATTEMPTS") + private BigInteger rehearsalAttempts; + + @Column(name = "TO_BE_PAID_FOR_ROLE") + private BigDecimal toBePaidForRole; + + @Column(name = "GRADUATION_DAY") + private Calendar graduationDay; + + @OneToOne + private ActorAllDataType actor; + + @OneToOne + private MovieAllDataType movie; + + public RoleAllDataType() + { + + } + + public RoleAllDataType(String roleName, String roleType, int roleCode, long roleLocationId, boolean isExceptional, + char grade, byte digitalSignature, short rating, float compliance, double imdbRating, Date roleStartDate, + Date roleStartTime, Date scriptReadTime, Integer yearsSpent, Long uniqueId, Double remuneration, + BigInteger rehearsalAttempts, BigDecimal toBePaidForRole, Calendar graduationDay) + { + super(); + this.roleName = roleName; + this.roleType = roleType; + this.roleCode = roleCode; + this.roleLocationId = roleLocationId; + this.isExceptional = isExceptional; + this.grade = grade; + this.digitalSignature = digitalSignature; + this.rating = rating; + this.compliance = compliance; + this.imdbRating = imdbRating; + this.roleStartDate = roleStartDate; + this.roleStartTime = roleStartTime; + this.scriptReadTime = scriptReadTime; + this.yearsSpent = yearsSpent; + this.uniqueId = uniqueId; + this.remuneration = remuneration; + this.rehearsalAttempts = rehearsalAttempts; + this.toBePaidForRole = toBePaidForRole; + this.graduationDay = graduationDay; + } + + /** + * @return the roleName + */ + public String getRoleName() + { + return roleName; + } + + /** + * @param roleName + * the roleName to set + */ + public void setRoleName(String roleName) + { + this.roleName = roleName; + } + + /** + * @return the roleType + */ + public String getRoleType() + { + return roleType; + } + + /** + * @param roleType + * the roleType to set + */ + public void setRoleType(String roleType) + { + this.roleType = roleType; + } + + /** + * @return the roleCode + */ + public int getRoleCode() + { + return roleCode; + } + + /** + * @param roleCode + * the roleCode to set + */ + public void setRoleCode(int roleCode) + { + this.roleCode = roleCode; + } + + /** + * @return the roleLocationId + */ + public long getRoleLocationId() + { + return roleLocationId; + } + + /** + * @param roleLocationId + * the roleLocationId to set + */ + public void setRoleLocationId(long roleLocationId) + { + this.roleLocationId = roleLocationId; + } + + /** + * @return the isExceptional + */ + public boolean isExceptional() + { + return isExceptional; + } + + /** + * @param isExceptional + * the isExceptional to set + */ + public void setExceptional(boolean isExceptional) + { + this.isExceptional = isExceptional; + } + + /** + * @return the grade + */ + public char getGrade() + { + return grade; + } + + /** + * @param grade + * the grade to set + */ + public void setGrade(char grade) + { + this.grade = grade; + } + + /** + * @return the digitalSignature + */ + public byte getDigitalSignature() + { + return digitalSignature; + } + + /** + * @param digitalSignature + * the digitalSignature to set + */ + public void setDigitalSignature(byte digitalSignature) + { + this.digitalSignature = digitalSignature; + } + + /** + * @return the rating + */ + public short getRating() + { + return rating; + } + + /** + * @param rating + * the rating to set + */ + public void setRating(short rating) + { + this.rating = rating; + } + + /** + * @return the compliance + */ + public float getCompliance() + { + return compliance; + } + + /** + * @param compliance + * the compliance to set + */ + public void setCompliance(float compliance) + { + this.compliance = compliance; + } + + /** + * @return the imdbRating + */ + public double getImdbRating() + { + return imdbRating; + } + + /** + * @param imdbRating + * the imdbRating to set + */ + public void setImdbRating(double imdbRating) + { + this.imdbRating = imdbRating; + } + + /** + * @return the roleStartDate + */ + public java.util.Date getRoleStartDate() + { + return roleStartDate; + } + + /** + * @param roleStartDate + * the roleStartDate to set + */ + public void setRoleStartDate(java.util.Date roleStartDate) + { + this.roleStartDate = roleStartDate; + } + + /** + * @return the roleStartTime + */ + public java.util.Date getRoleStartTime() + { + return roleStartTime; + } + + /** + * @param roleStartTime + * the roleStartTime to set + */ + public void setRoleStartTime(java.util.Date roleStartTime) + { + this.roleStartTime = roleStartTime; + } + + /** + * @return the scriptReadTime + */ + public java.util.Date getScriptReadTime() + { + return scriptReadTime; + } + + /** + * @param scriptReadTime + * the scriptReadTime to set + */ + public void setScriptReadTime(java.util.Date scriptReadTime) + { + this.scriptReadTime = scriptReadTime; + } + + /** + * @return the yearsSpent + */ + public Integer getYearsSpent() + { + return yearsSpent; + } + + /** + * @param yearsSpent + * the yearsSpent to set + */ + public void setYearsSpent(Integer yearsSpent) + { + this.yearsSpent = yearsSpent; + } + + /** + * @return the uniqueId + */ + public Long getUniqueId() + { + return uniqueId; + } + + /** + * @param uniqueId + * the uniqueId to set + */ + public void setUniqueId(Long uniqueId) + { + this.uniqueId = uniqueId; + } + + /** + * @return the remuneration + */ + public Double getRemuneration() + { + return remuneration; + } + + /** + * @param remuneration + * the remuneration to set + */ + public void setRemuneration(Double remuneration) + { + this.remuneration = remuneration; + } + + /** + * @return the rehearsalAttempts + */ + public BigInteger getRehearsalAttempts() + { + return rehearsalAttempts; + } + + /** + * @param rehearsalAttempts + * the rehearsalAttempts to set + */ + public void setRehearsalAttempts(BigInteger rehearsalAttempts) + { + this.rehearsalAttempts = rehearsalAttempts; + } + + /** + * @return the toBePaidForRole + */ + public BigDecimal getToBePaidForRole() + { + return toBePaidForRole; + } + + /** + * @param toBePaidForRole + * the toBePaidForRole to set + */ + public void setToBePaidForRole(BigDecimal toBePaidForRole) + { + this.toBePaidForRole = toBePaidForRole; + } + + /** + * @return the graduationDay + */ + public Calendar getGraduationDay() + { + return graduationDay; + } + + /** + * @param graduationDay + * the graduationDay to set + */ + public void setGraduationDay(Calendar graduationDay) + { + this.graduationDay = graduationDay; + } + + /** + * @return the actor + */ + public ActorAllDataType getActor() + { + return actor; + } + + /** + * @param actor + * the actor to set + */ + public void setActor(ActorAllDataType actor) + { + this.actor = actor; + } + + /** + * @return the movie + */ + public MovieAllDataType getMovie() + { + return movie; + } + + /** + * @param movie + * the movie to set + */ + public void setMovie(MovieAllDataType movie) + { + this.movie = movie; + } + +} diff --git a/src/kundera-neo4j/src/test/resources/META-INF/persistence.xml b/src/kundera-neo4j/src/test/resources/META-INF/persistence.xml new file mode 100644 index 000000000..42acdace0 --- /dev/null +++ b/src/kundera-neo4j/src/test/resources/META-INF/persistence.xml @@ -0,0 +1,59 @@ + + + + com.impetus.kundera.KunderaPersistence + com.impetus.client.neo4j.imdb.Actor + com.impetus.client.neo4j.imdb.Movie + com.impetus.client.neo4j.imdb.Role + + + + + + + + + + + + + + com.impetus.kundera.KunderaPersistence + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/kundera-neo4j/src/test/resources/kunderaNeo4JTest.xml b/src/kundera-neo4j/src/test/resources/kunderaNeo4JTest.xml new file mode 100644 index 000000000..04cf93967 --- /dev/null +++ b/src/kundera-neo4j/src/test/resources/kunderaNeo4JTest.xml @@ -0,0 +1,73 @@ + + + + + neo4j + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/kundera-oracle-nosql/PROFILE_PICTURE b/src/kundera-oracle-nosql/PROFILE_PICTURE new file mode 100644 index 0000000000000000000000000000000000000000..3f0b037646ec55f51608295690f8b56de8d94709 GIT binary patch literal 1852277 zcmeFZXF!ul*D!pgKuDBG2?`P*K#&9#=_C|Qs7aI%l312i7X+k82}vkoqe@wX0AY18 z#!y1D?5+z6x+=I*cR@gGh=_pF1Vq4IzALC(?q}cUe!uVi-e1o>GLtiB&N(x4=FFLL z&F;s$9|r+7h6mjPfPi5QWDNj(oKpIo6%r+k5`;wYaMtD)0Lg{!1vdc{L2WVpOQI-) zO)VnS6x;v=l=S&`k#E&v8TwC_4T-=fiK>e@IGE}$QtJFY51U)eBNtOJfh=;Ferf>< z%zg@x#TG0qW@x~=-Mhh(a4=O~#6Uh{ioY-V17ii2KmcDb{X%2Ah*|q5W>MxVFb@Dc zP$T~sU}K8ne=Pd=e^R!n3l)WI01rm6pHRxD2!Ohh0bmGJV81|%^!f_4qWrUNS1KS_ z0GNF0qaq6^Qvd*^09F7NfE8c~*aIZs8z2DS15toKAOu3eG!oeLIrj|^2Vw$&AdusW zwiVo8!e4L-sS4?T4}T%}qd+lypYf3~;o)Eo3P$B!Q8AH$0`Fa6iY9+9X9ox^!Q5h} zxS%P9M@0sM`Ngm)Xt(gMc^6?+#HakHX0U@pK9?_cSXmGr8W1Gd623_QvP1q>kJ4fp zh}HljVlhK^`-^NuFh44W_cxSs6hAaLG%_eMCIaMH>dsL}_g=(-c~$=yVU%Z3WDwt9 z7!(L10PbF1&}U-QCt?LgQ9_Rh#(_WoxBCx^;fHhGw{gL${-XT9W4r{xL4U(2`-cm; z{=t94p#y@#!?{86Lb`y)_1d&6Dk@wdP~{8yZ^X!uD1HJpJT&-=rj~u`Jnah_oe7lI%%Hi$3$2l6dn(0?aivMbm%Dm;q+7v-vdlJDaAM*+wJFry+Bx<(44c-}EW zLC{|f2Nez)(tp7&-4!JS4eGz(mw-bY@~`BJ^N*mY2v`b6=!R#D@FyRKS%eiPyy&Ok zhKu>lio8N^%K$1k!J@z^7X;t{77zl$LNE#zA<*>zn*W9Z2e<+pz(yhPQ;nbII|5L6 z5U`Gqk03qn@u9l`z{?9T192(<8mt+nC{;`ikYo{7OdAMv5mw~SLtvlq3VVSle}=)S z3eorzuV7z{AO~b6p!7Na3qe*}2OB#F zOKVUTpd^BQsR!aBg8u<;k$u*|$B&>_g?_0Y1;}7u;7?BF54l!2OM3?^vV)D~pLP8O z2iB$hhyK9v_)|BKi+}0{a_z7BfI`011!;%=(FR4c72)%W`uX?ckjgu{tLrx`wzmg; zll!76sXX=P@xm3pG$K;SXM4KfwteM`L)-&3z5-Yd7z4)s0RkSC#oDwe@E?;Gw-=QT z++3@W^^YX~Yosb4tPpG|4kW<@e}WZeiP`lDrYYb!Ax{X>Y*)YmA^xCqgeZ)B4WG+) z1z`yYzYAW3p~n>Pu0mD|QiJlb2io4ePs)ALq7$Z6E@``#T>$zP<4A3ZG8aH@FF0F57xIB z;=vRSt}_IH2JS0LfPM%L5&^jeHH2nC-@;;HZ{Qh9`bt-oLl9WRJ(ZKlC=_kU>ZRJM zXf%4+3N@m-n?|VScbJalsw=i>pIM34O~5|akH@JRo-y8PvSd{|p};J7jl20e3ll3- z8yh=sQk=tSr0|kBBjd zx7$ZQxFzZ9)Nj&vWd$7x5rr2-e;4=tAxY-Rqa~H{%awOdz4}4_oL6mXUDGdWS3|D- z)@;{S)q(FS?=`=3+c9k3bL2UGzA z5M78L$P&jZ&NGyCE{Sdr zJ-z7dn>I72eDb+&TOnVyZ9o1^+%DfB_Yk{1t0VEz2EvtbS_!HLfJ0A{Z>C+yIQngD z4kvG&c*%ET-?vCAPv(^DmG7wxJQaL4=BM16x(lLGstRi?CYQ?Xb`jwW(PYBUkk5O z@=}^oK8EmCQCE40tVc{Lh_9MYWbZg8Uh;AZRb8=b$2$ei)H&Mn_s=$pHv(62P0 ze)p}=ml3)=s$h3)#$NgUONW}1e@pAg==`=L=eN8zam&%BqNWqgvbNH$^1iBx(;t7- z{dxWQJ@qBOJZ`Z4HMe=TeS1eow?}W&UB>-e4+Do@KgpjkpX!*6TF`iP{@vFfKYp64 zi#89Q2R<49r@8ab@Td8#D1(9iva|sJwt|rXMkxgVR>gtq;MV}a0%0x%fHeOMKsrtX zkgHEX?-mazoZkPaSq1j@f7DD`?C<}e*#jQ%7S}Ye-vFRzWxX~uG9U!!3LZEj{Bbll zoU4C$=&nBw7mGyTan2f83m(@Z!Q)&Apx6~E;2nyC+Sy`iR+`4Bh=_1O7&-C|T6(7t$c`Jn_#$6(xTo4Gj2$kO!VY7rPV~ur4S( zC?Y6QC;(|K6>42ArQL9g39^t%txR& zPp)GJ38G^70YUDuU^9&sE#x`4@`L<^;CT}~^MVGz15c$f{Gd-oUQvOeyZ5?*=Y3}* z#VKK}g*Euc{c`$P3y!^o#b2ZZ{R^oT_sfCeucTg}(FOVo{r`pdzsgmNkOMu!KR9S> zXrM3zY=f;GSlyrKO+k^t3cRJAq8W>L*Qf{{KS&?|?FPhuMlPPHKwIaB2GApgL41%x z=&vv>P~>M4@R|cu$!FvjK8}9`IMoHLAU-QJJ_uBg^%sHR{*nHC*Qm(dp}{er%lcbw z+Z0+3kNJeOwpa}7EEPYWxxe~%1b>!qjtm6{_Dds~U`??>ZlS?J0tMFAZjF_#Js3$~ zB(DKy=Nc<}8!&=6lFb@hYYQ-1f-s0DS+B7o+pV#-uv}wpNdhBzjja_Jt*t;DD97Fc zj3BMOB5wHgDL{aN*J7E%2)H2Er)wsEP{)55+JCj4zj1(S2o;7V1cCnV z-?1#-n{Ytq3EHupt*y1~=SKfspVoFHJDW8&7Gyh%#T3+(y`|Ns)M^p)DYXXiww9l0 zY}P2a>=#o|tDwd}448r#8Q&Qi7?XE^BbK z6se*XYj6}5DaZ?^i@e|%+F06vrHT}6Etr17*e}8)MM?(S38srQWLprnw^HEk!SM!D z&?;;!$)HR{s^BG)6ue}Tf`&{|(2&WCG-S&~SRswPD2+^3)JR^GNmjH3RJ`39&~ny* z*0#oOjr|(Z8uA)YHI|lZEUng9TCcIRSp!-UNMvch1~fY>kQOvX&=x^6wFNB}G&s;U zL6dWIcd>9Gk=-q=EnMv_$?jIxu4Gp$vZb4iEvOMoD;pzRV1UE!D1L-LX!@ZFr?4)J z7ZhxS`@?}cEDkg1v%paXC+eSg@KS-rkJ=p?u5e@j&9-CFlX-bL&?5yx|HyzKx|_2R z=poHRLjxT^>-VstM*+ZSH9sDK#78t{cTP{C{e zzsLJ!4*Y+T0j|7@4$vi3sBl=HT-WF2m=hHJ843?wZ)xYWPO+kb;HSm|(FTU?_Y`~yC@#Q?>k6BKCl86Emh8vnOi`y?_hBuL@M|Gqrg zI@prFtT~^^1W~(%asK=uYA`rDUv@f+3&Y|Ep}$?V8Lj(6HUHY~s7S?i?w>8^`Sbn3 zl_iKTa5mb_kBY#3GEIe!aKfn1xkW?$U&<8t$NnkrA2mVxclPstPZOW}58i4;1}j|c zy8pFq{(V2l{|Eh0TzCE-jOhQb{rI=O;J+D<|116Y>-7BBnYdW?m+drY+KVV~kFEg! zI3BG3vWfrC?|(G#9}WCR1OL&$e>CtP4g3$%z@Hb4L6P8AFAlsu{CFR{a)m(^L6O41 z09S@9f{L=Tk}^^Sg+i(zk*KB1mZFxRmmra<>Z<5vYHI3gsHGa38fuy#tfmkGQEJXSZj&b5w@te60y=zImmk@x+n>>1%O0~GM`mjnP{A~iuE*?SBxO*NE$EFYJ)iMPZZ;7cc+$1OR?UI8-LqXYI|kuw$zHex&BA53$5+uBn!EdpaFO}rW|E;{!b9J_>D+)@zRm2E<9V#%Ij0Y1l!n z99}-jxZI0VYSS?wwqL}~zASCwDz`D%%1}}>kFci$3TSQok*=2@C^~LP*PsL8#yV3? z7+Z(bN7+JSskeNi_pgCj@KcfTFJ@Q*#$J;#txG1`8gxFyIAOLI)Z-GQy!c9Y0@;KN zld4ROcTlSxAk~jVahln=zK&Tgug#ki@Y4838IqD*zwJS4K6O~yoST){!xk}kc}3sJ z@yPbXt=nHrn}w?lS3gyP+Kprn8&#MP)Fh;9v4a6;9l0}J<-M1H4{DC1IIi9Vrs^6O z9si-w)^II;W0n~lQp4l#>;A3e`y*rZUwaZ8Mt>|>x2xERokqy9ykuG>qbO0UpJM&8 zhYNDVA--aESrj(F_(z%0p+u>y(;Ex5OeQ?VT!BQlAxN+dGjcZ@qBjwk8ho+v5!hQb zP<$s6X?aqd(vubK$-5NEDO{~fCw&ACg{^2q4TrY(JB;W{P%t;W@-~M9>2u{&Uf*ev zihf0{tH0MW{x`?ra?_NSFuf-C>uRS{UYefKNBO#!!TrhP3HrDj&ZAdU!E0qX&7BN$ zBwie}%7^j~);cj(np67^jSs#L(Gx!uo}&1`E8h%bxhsiVoA_+YcF(I?>+*4Uq6uRQ z!U-Mb%jsAZ3op#^j(k;mQ8#QWMjtSBe!1+i$15>yur8lsY>Ey12rx1?&ylv4<5NIksc*e_8ZJm)E0(g)qc(APzqTaH|v_Uhluhn9yt(_8uNgk zAYzgA3sJa(PtQ8 zoZ~rHc|3XK$fXRthM>iNhEq?`OxI~^Lr6)sn&CwdSfVl+JL_XOvLf*0aUj--dsfBg z0S+#T?j0GKpD#TpW{Ya(Jq{cc+Ys`un{QFk_CAOlcPC*d!Hui84`P+Tvor-VkwK+wjp&K6_|%wcdUm!SKf2)lxaVcB2;S>0 zoMig@r_WXOm#1}?B{>!pMmDtUtaZW|T^m&KA+|XAGmiVmebW>Avxd#{S~p`v4v1~>>LKtLSq2(<6X8c%p zUw}^Kx)@|x($@(~d35KHTUEm2A_%bBRIbN3J03kDDZRQr<^4w>jk#PdrK?d%-a9>z zQ@1nkbE!xk%Upi4*`{_5*(L8odO`FQJ#WIEp{Hz9Zs=*IFB*Uti?$E$a zU-O`kGXHi+n(gKG3=h9(zUA+N+|d2 z4RJ@VT<;z^+`qyPEs!2lmQSRiYN~-#k(M3H;MbSX_>#h<2{|>w!J`p9`22jf6oI(B zaxm>~O&x9;hL5?ySgCKeBWwk5dQ|UcAH8_FW3mOq`>NAhZkISb?N`XQmhkMZTNd)) z=-)h2a(;zHrFeCB$&uHR81#mzo{DI8I=n|R)qi@LJbK0(UKV%O&{fCSth55H;|x|~-B1UF|qFY9&im|O9A4IA3iqc?f06bgGc|@|vbpZDw}J`eK4$@^o?-7#@Ni7(9j>!ght~Q$Z5&u3 zEd{OPN^exsMtVD`xx2-?7QUmrjSM6&n_pGJ5-mNICb(H-hI(?MmO*Ov6!aZV;r7yL zY?KS_e$xFntd#^8cD^Ts+^O7Gq)}d_b?w^uXH0a0Sq6s{ZnFM5!X2%P6RysBb}-T- z0hZ-dwPd?8of$tkGMqBSxlC;{#Rrx_6J|M$TKAX-14s3K;&9L6Zk1=BPNo6R$sdF* zl#E+(vyhy0jExzL9$k0j7g(?Uyxq#mkiz@u1lauwtu;I|_H-7aa_XdSdcKxB_$U?e zk{>@@1m|yBW+NL;!v*|ka664SB+3To)UbAG)5gI%?EXtC+K7j?Dijk|TVub}T12k2 zaW_hA9?ExyOuei`a?->Vqy}%D%GE`yUO;Sdfw&JZ4H!kYs@jMyUCKPj=*e-G8Z+ZI zw_4l#n;&{)cVcX4WIAmaJBlqTtmH74i1Vo?r2DvK%H!rtdh25+3D1mAwZTW= zcpktFoj2XLO!$ni4IS-MrSoeUgJPUMDzi_JJ#t{eRDbmqR>DXkNq&p6SDXe!k4<9tsJ zsA1JcqzdEboa=#adV6t_vf+_IbiIvoRl^z0IDN{fBv_Adt2jZvrN?17$9Y1vH};|_ zTuya+6TIqh->Or@sC`mf1Wk8NHylzLyI=#8L{XU41g_ z_?XY#G4Y_#(6j1>FIP47R`iLMF$pKKI(kRV3@|vFuksOyFP8iISFu&^`XEU_KpxfC zZj&!n8+a@DFzardj+gm=&2m5sCOOF|u2fuS_w!_}&Shu3Fn7^J7mVe@o5mQ-88$v5 zJm1q9ks#s1vZhiAgo+P+8IK+1G$yoV=ab?Q8D=eyhQ}Y6>nlk~q*;-juReU;`^?Sv zF7slKWdwO@ zp=x{gN|WZ{LRj`_1p{m2W=`z1d!8T!7b96+*~oK`gy>gczUz@1NM_f8maA{LPCZB5 zeJN;~%2>SVWp||sjl^>W@2ZJEfV*F@U!_#6C1GRI0s~NE2u@FVs~T#mA{6&r$<4N1 z6yY-#eKXgW5N85$q`^O!XB7`g_LLm#0i1+43>bQ?c^yWrW(}{ImQySxtjqSn$6v=C zAaX)9)+`-)WSo?9?N~@k_ zd}ZY54{x7{%av=9P(cnqVd+auWPW~8O+h=?0^vHzQnP2obelJ+*X3BYTy~+{Tf*RT z3O)k0gj2HP2YO71@PK^BH{JG4US`QGl~D;ef5p{MAgQdj1tBz$lp%I@O1{HfcC3tJ6DGQF6{bD9eqoK0iV1;9M~%eJuacJoauU*1|E|F!*LvHu z>yU=#W#PRul(D)XQtSBSz~OOEqav4c9te_YmV=>3kJO`QU*N6^%!4Kz+xxf2A_Ox% zE913!qjsOnB4J+wcb1aH{EFxVN$CWN>6s(PYO$Ipt|lZI6161w)5+c!!kj{(USXGr zaA*nA$uD@)rJlGav(eCPbxuhM5d|5^o9rnGyW@V}#nTi(hbbw+Q}gpri}G5WKZuFY zaNo`A0M!;mzNhc;N=686ykMICq$GuMRG06QJ&fZ%AeyX-9bQ`*-FCmIutZAVfNUkV zwZWg1>^ZZQ7|M>7EG$%2r}p`K%!;J+`3|>>Cz5%MxMA6R6P${)lmre>`B1N9s`Nwf zIbk@jGPcLN5scJ|Buly@Jnqp`_Gssb&$LHPZ97Z`R*SLQ@e_X3DL@YW{tWGF$GWjF zU$|N*k-2XaniVkcec{r;rBY<41;OwKc(s$h^m0N^H@kgLN~8vDjNW8H&|Q*vZEuq| zW>1kP19%Nk(HKX^@^)7PD zqTCzQN|N^l3M56Qeyp-2ie93y%2Rlu(fsL=tC#xYY*uexm%QDd1iRqk;4_rzz#c?* zQL&>Kk5<(h8keN4e|@Qj*;Wj_Y(})SG8h4HZ3ddVkkN zRv25qii(dLZ_-;}zu0lh6Q8?DpK!-yUC~}8V&|Z8LU7Sa%=Nr;{xt873$R)}W`_Fp z3PN;Y0Meik(l4F^UzHCImA^GSKOPsUn|x@4Z=tWok>q+R1-e%cX$<%2c9TRJizqE} zrpnH$y|`?Apm5x?Q6n7xdh6Rd)?`jitV_z_-!ew=Ne$zidgj8z)dBq1ulGJl)2R5Z zicyvwxgi~+xh2!vIZ0AdzJnF2#Orc)qleAw}HCZCpSt0IL5)C zgO)7^d(~&Rqv@lt@`U%Zo`LZ_{B&KHh6S0Xs<0-rk%U6Fu-x@R)uP;v;irgZI-LR^ z;_{dsl4X6S<1?H_Gk#Vb4mkAi?b}|JI&r_q!+N2#Lv1h7I(3+&{gz#Nw(Z!K=nLAz z@Q;8)U~QvWep0fJG@4@QniVpEq2hQ4+*i6Z`HsllV0CEPjWb?qB_e4RLOfSw+p&b^ z5l?2deDiXkq-fUrb4Hl%y8P5ax?|xxVGhJ>}H5keD zL{|)P^bK}B1yb2t?#*P$nzIe02JOiXuUZzw7td_aIi)M;w0m{BXc`y zafy(vZ^t>wN_+|t|I9&MDlJ4wR$#LI2{+)um%X?$8zk-hKzhZ^zKVq9#~Z%#8O;3+ z-0PpP7?Do~nVnO?yHPgQN_^3VKAoIJ@WEYHjw=qdK6ld*BFl^)eLDHk6LTd~0vm#OEgL%9WxiBxTv z!KN-Fk#dJ=-2A2-J~?g*QxT= z+syR#&AC!9hM5NTs7yHS8#+c{S8D0Ih`kSrAxJvWg45{itz#qH1c7F8D;~Ep5x7%w zG~sqpYMOBf{_%Er_a%1C##-_yT)ktXEa$knAarYZUN37o6b*<6n6w7uw8LADFL(CH zNvjrY_JaI&_r;ZGcUpK>O@~36G`8YnV5s?*3snQ(SLE$@uFs`wkI%5%$w@mNrw)gZ zoTGcv#AR%+I`HN~?>#}jBSpkOdzxltMbne*gLJ9RmYnaZ)vud0Th5Oqa0fH&B;KSp z18NhhrV)pIPMZAC;a%+%vjaSAym#omlgw%J5EpdmzeD%7U#wk4^B90M6HI$Uipm0j zf)*RDg*D+E7H4F$ z`bS1#k~k;zWwE~=y?fOISs^z1<{O^}jN%~ko4MjN{cCBJp73MF)faP)P5GF&*;U{Q zkK7%0UN4TyaJh6-ERw8Iuk{=4?^-!_;@7M&N-J(SwEQdCz zv<6Kcmb*!bTD8V04GZKBHE~YpeGYg-T(mr5rB?N>pYzfJ6RpQWvPOCQlR)nQ`tRNKBC`tHjHpPq7=v`CJSledWfbIinkJv_GIXTX9D99^3-!hsFw8>t z$%(qaW4Dt{MTwI^%f65G-X7P4f*bEX%0C@_<8}rAXegqc=2Wv?DhuI-L;HI-5SZ{5J-MaiI*IE)_%W621-{XHZlgB$A(q3oi0VcwCIGhj)dM zj1`_|icQS-)Yhxa>)3dP{n*r0kBmoQVkx@Y8Jp+S1e22C9=ZCtqy2SL_mg^OQ?k2f zJr8GECKVLqHO$MB5B|P%1SZLwbXoAI!y|nj?ZrvSO*TcTBw(&pMSGhXCpy0At?AzyF|hgWvV`M?U#H!JC$psc z5`50s_>|vS1CV`ie%V>Ddd;DN$hg%ZBg4jL+{$(~l2t{;V@z+%S`zjqh0R1V2d>m` zmrIyD)a-c9yylK0ci^*K!_uprB`%s66q%05DbKh?{OKG!UxX4Dj3;$0Q?l!=NPR{! z)$`c9P~5c5PKjSoi+gFBXcn1ylbeMoNyxYGaw~7^Hh)-1?jtQscDOZ!NPKR5r_zdj zapO%FyAFQ6Opa4emApOKndusFM{8-suy(`xLZZf2!n&wd`c{e=ss`Ps)uc@~g-a`J zH69z{m_TdGW!EhkH(ib@;R!K_*R0E!>g~EHv$l^wpZvL74e2ZmINYjVUo{}>>Iuu~ zpF8P2TY3?GJJa(!Hm@Li;f8X_i4%7M_TH~~ZrxMfxDl)I2tj`HLY9FWt4sCER~h&5 zTFp%_XUD_jZrD9Rzv`fr*1xiK6o(K!o_P}QcY#X}>}$4|I?$uq7^s;vKXhd5nDllP zCU!7&^$$8#7xkCq{%)@hPK0IfIA;IpaGwU#t8#{JIf6mt7FP1;xIh6#i|~vHIP$p8 z-nOJlr4UXgQ`y6VUz$@(v{$K(c4q*ca6lZD!!+FzUuDlAGMN6dX+{6Ay_RT=yKpHy5>X%=TfBiDEp~QxME{s zztiu2xn~K{Wx!=lvQJ|pFuU-wYIgx(!(>~W9<_mVg=Atb>BR+v=!;2}^zG1nNgtre zxU_zQ<9hL>S2AX*y{cN*E-<~FdS@xp?HbbvT<&qbXqT!bN<^HRW{$TGxKt6g+C-k; z?%_FfBOHCw_q*?7_x7{*V!57Ijs|8=Ba9{UvQSDrp?~kz$G0;#b)PA02LcCAZtr@) zREln8-FT#bZF@vT%vNvCFY{mYqD5^O`hm zMmTz+ZoI==iNvO$&YfJd+PK_{=)`?sG3ES<-t6eJQ7BHiKx)(fh3hp`7^+Kk%HP)o z?-Lh{Fqm|mmINoCr>Vz=@o|$r%#~#f9$Fc(o$FFlmMBp>4e1>%@S&c~bkW$Hmm+;F z^NEzN>N?0xw(NaTDZI6Eu&&I{FE?Djq;Tb+=H|SIh+6eF=&>>ric~N`NG-qMbuD4( zaKC`l1nbWWb&M^H9{*r#*NclSDdJO&Ns~=XhvMp8`FxFN33!o|d}pn*1@x!peW=V! zVn%pDHjmtL#(fE${^M%dje%r|CW@w;R9Rm7^`@^{uSM5MOV7a3y_zUwBP`eVJ9%Y4 z^U;y|4ef_pHNUqFh0oUU za4@_$GS!H1O!uaGkwb{joM+v?s%%>~`&rw1Y;T%wA7C=^hg| zLd2K7jVrEA&bd%BEUm;A%q^YY@R(CqDbzJ#u}F1sw=(nZ8Ara$VBg*VTp-`o#YLd8*ccnN9oU36W)Dg3Ws#= zl|k-7U7qg0tLI?w@-=ssv$3q$WJ5Ykno{Ioyt%|Z2LA#3Tp;19IGl-Qu=%CamL4-f zswUVp!YRGyN@$9bhI%vR;CA8UrT0TwM;nQ(Egl-yeKHlz&^BkbcetOvD*BnsVM2tL zGJa}(*-~qOkE4GC)`*kQ-aG3{9DQZsrt6{&QZ=*lC`OaSsvEGMoR=+>4y3V|OqWb# z^D=h4j6%^9((I<26LLZ(GVDU+y7@?Q<5Y_lK~GH=zg5XlMaiib8{vB8+l+pCA37w3 ztNs9IqPw}KEZ_pi^I~szl?zQbKi(-Z)GItKS}A&zhkWd8b?AitTbB+|q0VYkUL$Gr z>f0wtSWRd|EC5s{I;6hoW=&OZ!k;3VYBxKFeKnNE-;s#nMckpDUwIr#@tLsP2#A}CV zMtzo++*E08B(*yA(p+}P{2h4+t#w(pbeF??OUe8syJnM$iCKQK$Hypuy|w2*a|IuL3RL1zm~wGNLME@xEMCcVCLk@p7N@sGn}m0 zQhdzhOp!#m$FUZ0;W87qP}7jTna&mNX}zMD#Xhax*nPvl3KBOz=!n`8#C^44N{iY{)hxm$m3)o zsB{(fPj$J67GzEuB04S2KRD%NKr=C;rxy;R-_P7&p|=m^(_eIL+C>AvMlY0j$TiP} z<>y0MSb`Z=XbETI`N4qouUZnm7fmyy(1Mig`5Os`vy3-F%m+x#0_lkmbjYo<+lX{F z89Zj2`L}5h@C+*zY|gu`yT#j&u7RbQIz2Z-)8bN7d6v@p=7b`f^d(4kYH6|@tG{>B zRp?6DF5{j~gnBa)yI9}ei~U_t^T_yuuYHMx4NzdAWNh!uMwzZjdy36%m%y)cL^C-wzu+?mK+EaviH6mJPuTMoY~EW#QsuOgu8cUnjq8Mnck3d&e+Qyn56%rnxzv)IYSP+ENN+4}cH?hBm zqhsNclTXY-n`s>d+U=N2mukvzHpoRn=`G zgcTqsN<37(xIItHng=y#8yJq5xNf3OGXgw3Lgm}KdEtrs)bHCware0OoM;$)J1qCc z)G!7CZTQlKh0^^#vm0~P2R=)PKKa7vl&_sPwDi6570MU%vWNn>?r)z*sR$jeum>(@*RVc&Es^9 zn&yOQ4v67p@2Y9Ewt43<)#;m#EXs}x#!qfAA1LYGaYrO@Q<9Nnn0WLItWo{qkP3cE z#~F}i+N>a=#>j8p`25u5+Fys~Q#-q*%I;olk!EZaER6bK%JTpN>FN(umc5CQd5x(* z3e`xd6CLcOcQ2LW5ZIUrWrwUHL-**;;krPfHc3`~UcBs>h)=q42gA%#RTZad){OY+ zSG?x_s2R33{55Yh(!=ZF6rZn(TV0r4h{+9)t6Ud|Jx~xkt+QZo z)F!qYRomXj$;-QMkdQpZTz(>-BSOG{0BsrP8+?+X*`pox&J#OQYu3fIPXNsayeOoS z;Wpj_$?Bw=aPDA=w@sO8UOuh(?AUZcwg!cG1HSC#hbAk>$U3|RiG&@Nz3Jlk%C9Gj zA8l*#neh<+L|-2cm18{xUN@N~ANCPZocA`V zn%&f0iEkiwl1y{%E|gXhg=JZAwbK z-!Lj~QX`i?S5|qn4f~?>Vi9oE&s4t|dbSuM)Lka^_Gb?I2e?th8;Mb6NLM2W}L|*>}?SIQ{{d zNM$zUub6osq7ml?;fm#Wfa`tr%#vxhBeq_xcqPne@oQd4kNe$g8I4XTai)VD4o@Qz z0nMC+)xIdbS}y>WoX@#ql(o{7Kq!08BMpNOU&2Hq8b2H>m>eh`i>H zX)@e|6NC#W2H$R(LFKF;3-v5&gU@^Vrtd@^kExElr4<1zm5j_5otS`}!Cd)D0CBB| zEVOeVx{YmxS7J3qg6!VQHZD0$yyoGwr2$ze)tldKI1(UzFiW*Q`*ITt)qp^d^oKH> zxT{_;&Z7Hy%X~BRY-rZW&`S%Y^eDGVDlR*xzS+718pE>dsnQ{`fc*HDGjRSb_6TX2 z2|OVAKMnrEPf&hZ6r>DE8zPuf{i^raf-R*;A?CzLzTy{Vm^2Fw6$SHg@Tu(4A1rD zCH#1xE)n^fN^Tb1E>TY2l$Xy#J5R*pu=U$;!KPQjlx&7B&F-&q=Fu14a90wT5m{5$ zbI_1+AKld%ES4GUW|mat+sj+^hn*3>Nd;7wtyt+kw6hs5VwEz|XZ%i1NQupZXzj+9 z{n;lU`?!II%XAP>#Ek@(d`2e;vv#FXJB5r#JM`9^k06qW#1^;&;>s?%`SaY;)Ok=- z(uJC07&dlPdwgM`IPT*2oLJ%DT+2X~@5s?$9AGE?eun+3973R)(H=Zc>hCgjBlPiT ztvbjp8w!_r`<4+$`J3-ZlCqA01lZSm_A$XkH%CMK0{ez#)V-qQU_W7m zpzg|4$*Xo(y^NuDI*06dM(MhR8%*>b$VxnM6my=-Np=jbx3yJ~oUg;l0I@-RYbDJ= z7LHo-U5QNau7v??Has@VNIX%^rXXO-#moms%pqZTzojwIq;89ITj3E~yh)SbQ-?yc ztT;dmcIS4|1O0hPQz{e%toQ1>W+r9Bo(YO@pX+Y3_Kp@J?oZhu>g-yOFJ=W&3oXVItktz6N_0DMQ1a=*tzZaR&`RSjlr ze4Yr+)NwlW6GwQ5%40;o%5hkbagj9Cgy&^Qf95S438Wxf|8U82;wmPx@nwf50~%_S zFMciqZn*ZzYP{gzZ*@%?&l1bUC$0qCcVfBv-il@NLou20j(cQLPJCc<-*Ro;qk zB@)SqAB-#HXfxF+9OEJ$cB9;yH70xLHd29;n;AO|&SkMAL*0 zJRS*rC}C7*i2LrfX|7zi8%F1&H42Aw+sp44%R}lNZzd!YH*UdKf?yj>_S<%*>vkIPK1$wZET8LY%~AB}w)C{CGBqIkkDG?H-n zR9J=2z>yM&F*nKdh)mE6zQcrtLE0PvN#Mv!Z10blrzh^Hwlx|{OQm7P1EQ3Z3nj#L z$(uEg{F>A(=#ycgY;Slbjgd*jVNX`bHDp~AC+2W|kejA`a_Gsx6rA7On5W#UCl~XJ zh_Af9M$NX?oa|!;gPl7NGF777S!LmEiZh6OKX# zUry5>#H^f<0E{FS$v9CJE*v@J8or8QsJ(?63i0{9#c_(T-Rzvo^@~yiHK$S8_T9 zku#DfElE;A>6-V^U#|dfMz|L}zkWc3($@L#=(~{cBdc;W z6M1YVWWF?%+HIp=P%zCTS01Irc&p$>$v2GkJ^~MI*IHoN;QvMpKCFkFVK)(=JYb4A zoKxCYVw6Qe@e}#huely|P>~_^pg-Ap)-w%W^q^dS+3yM9s!exy45N)ElbhVvpGs!O z6Jb&Cx4kZHx_GB|#fMfMtns|KD;_Eih7aoX2kX5zBc45#Y39@TVMmi2V@M>;ob1mL zt5q`xMa+lg{X-@Gd-B;<%K)^PJ58_Ejg`BJ9GA^j()(p0s+#9dg_vo#4(nB}Dy3Se zUKbbo%}HWPV=nGs@EG3hB^w-&`D=i9ydU^_(Px$+Twa%KB{v=m!>NY3JjL^6aTUGUOe2ZclLZ87L9(GAgbVI-n_T1g{5_gVRwU2;Q${$;C>FizgrXNllrSS#xr z-p{M5T&j2o6w#+~SUEStZRa?qAmx(NGwX2{@$7iN-y=ss|A7QnnebjT(iDmR2$(x^ zXIaxlnyn@~>hzOyRW&w;aPn1@$S=olVwNTNmw%hF!Crg)iJyEJ+chsepd1;1)pbm0xjc;PUtM>bgeL?b&OuQzZox(NKlxCQ#7#{ozsxtL;# z=WD3o-pngLUm76*QQ4F>!r;;jr^!}LY)T~FVBQ_=snD{aHv=<0xmtFzJSCKN+l`2R zmT?yAYdY{CEjpza8|^k;qWiSoWoE`azwJ|w^weVj~6$tYgfK`=RCM+EwL$pkx-qE!&URPwj)P3(oRhHuxM~;NluE8 z@^hOxijiTgjS~#WLym0uHe<3baF{f&Z!L z(>4ZXo2|l(pdk#;c3ynzjfCUH=cw%zr1ttkbhWB`>M5PAcmP3h=+z~7TGjapB(oCD zCI%t(5*yw9eE5gk<(EpI)a8odejkA&?&L&CN#Rmhr=TazD5UaMQev9)m!&VtXNX87 z1wJcs41Uw)KtKR>kzmJ$f1LEOy<3(FJ-EwLPCdsdmj7BlB9Y8xNn%(bN0Hb>g!8_x z+m$82c8x+c)WMyp!neIM9_g4mT{^3|J2B)Hk!k}aw|j5$J7jjWKat^$TN-$XA+dFv z5Up6hs}OSGhsQpKLnjh{5S@BV8Y5Q?_+Z>I9aZ%EH6k*3p|m>1Z4hmxd9&U*bYJEs zyV@qgeNiIg(rATqNME76!Vi*^PrZT7n=c;lu{oXuo{q^awctBSZ|G4N|1i(8^+PQg z=Xlh_SPxCe0qgjwzTb%+A{lYcQ2U4$*JNwZe<{z}h-(xlpSgC9^g&vL3 zzz$dJ9Lj0k<{&q8q{AwkmC%GSkqP+C4E)ry(G0bnkz`7S>7O9T_T@`pb0d(}1)J4g z7~9ZgkH}PDG|zKa+DnthhVgM}uX@=n-d=`z@d&R~&Ixbr>CoQyRg3n&yCf`^Xk8|8@y?oIqzQ?QtWt3C3 zonQhN56)haIy+B9cLQ`}74`q2=v@4gzWzTBf})mq!_5mACdS28R%+m-z$;K90@miN z*{Z2j4!lb@K&^C&h`5>(0)m32wWej+MccgYoA+*BibOLrGjBDk_4|G1AK*hC`1zc3 zUhn7gb)eOd;lx38{V-A{RUkJz2l0nynLl8%+}FtSy}51ktsm6a^YIpM2X)`>F>a*> zS?A$@T8>v~;L8go`x`AP*Jq6LS}}02(f#@S=Q{W06AqUkWkZi2)rt>lD9StARwvY! zn?{1k%Opb*PgPL_g98h|6ms&tCX;U2Sl2~miGgGZ7U$|_{hbwsaq>9GoKE;@-{Ywf z3kwP`H*0-Impfdx3%RrKz$_*yD)7eIwF;ARnf2P5nR>an`l2e!a8>(rY%8wh{LSed zO&fiNljN9GCCp`(UQ@Z@N&}A(D4KhAA(cE^7oG<^YHRgV=&D}Tgs86Z&56#WHkkSq zfv4O4H1nYuqn|-+53}^X3JWtX%mHZi1G?^S%I6;jYP@_dW?bQ(SBROT`vOr3 zjBJT{7ZsM?IB|Zf!)>sHmjrUO%hvA1J(1?L^-;n@Ykv8?BN7U)tw43XJ#S9dVzJ4= zI6mu2cu!Yb8}eka`;;X$l3A+wvaO;5e?mMpspX4#+n7IV@_tA)78%RhT%3aJJPSkn z{s+d^4r(mULi4m3ghZj-7Fy`)h0O|#+^+ad&Syjr4a%MT_P6=lFu4bcyzlGi-BU27p48Ag5d+WWs$Yj!8ydf&o6 zaj8ssJgpZuuL-WBM~4uxMHLsj3+h9{u@FyaX`ipfh#@Sm5{P3hO+$VbGq}olc5X-X zqe5SnUJ55pU&pcXUP+IQZBuR;`po4;W<0rnTvXP-n1qjKL0>$0@f|XErRGJQ(@0}w zcK5dvVuV6&L`=Kip5#nc9thtsm|J#(n*(`N^GO}H25(r+%zaE6otX#1acHd;#4tv@ z=pU5Nsmifd#E55q2J_kJe@1+a)AhWcgl9c5j`(YcF=@gwk zd~khDw`k&g0)9;0JzX}||29$_rHg+T4KnF=)!WU}LC#)i+c=8>b*93hY)CPg*c255 zN^uk*g*mhHF}q-#cd`Jx$WUe8;0JlzroZ%uj9Hz!U0QC3!QZ~?RUm{NCDl0ga$Z_> z&nuUG!44aTrEBfX`V6Lj7bqKfbRdoAxV|mU()TV#yxST~ny5TeKn-FUu`bNXNe3L4 zA)>2qafD?{3IBd9tb8L>vE=fpghSJhKQixfTR~A9Oa2O6OnUC;y^C&NuC$og))&(b zY4aIw!0%@abdV;*XT$%(l-&Sw)8DK0^dn+QzGMHf;FD2MvsmbK@V|m#cB)*pd9v4E z^3XB%RVmH%v-R?Xs>#wVZ@B1?;DevTU@TPs?n(mTXhFl8s|@QimR*MH=N2CN(dp$q zS7GaGdiGsp8IXrkb6l|XAoas-$@n1t^L0HXi1IelcQF_^wIi)dMcUxsoan~1*l{t6 zfqNYe9Yi$nh&u(9ctbz-=*TH1e~d|Bg(!C%GClY8rBmH%q`;Jcd6M9f3RbHuw<3+Iavr`~3A{uE;IQn%8fk|}fg^lFntdo1LZoA(cjMHZf;23ln z<5@N|xATszIjJTqkZe*rJL_eG$5!vgPiBxhorvhbvcjC6@=<3qaoU6R(PRarpU)hy z-lx5vy7iB;80)X(MTg3i&*Lg<_DMRCnZZDEji_wjU@gn6Y9BdU$iDWrx(0S|r1-Vu zh3|`faN7JVGwDoa+-?VI*JL6P=RXsTldNA`yyyc)eK_l+JydLvI~Z~Me&FkyVT)<2 z11eF_5YLQfg|_eZJqAi|?7uiBRz<+#EYCbM@T>x38%=|1Cb-R4nD_2fF3Cb;CJsj+ z$k{xr&fO)w8j(+RrcoM_){*34yl_=>840dX*x~Qt zyC+W)fEQLtk{8;fq^Z(FrSZ&&5J7t1!PWl8q+fI{zsLSQwL(Oz42u0JEh8@~D) zYWru?&iJ(DYVKZi%a7!qcw~{HG^DrP%&)%z9Emx$8XK8BZtg<+n#Q zvG-c9k#7x-uHmwrXl68!;`qQ@wvf&NO;;T%l&gaVbriBVXQuR#+DXr}Z{J`h10f|j z6UBp|{oT~AwwT_e99)LgO=x1K56@PRfVW{OyvY3A*69k%515hLCZ1;vxLV*5Db6vb zn`(DElA(XfxKgt$V4^4{*rbOv(pgQyNaQ4#X=iQG6>q`uiT=C)Bj-h(f+f0%-SpzS zKE$bWHaDoWR*cZLmY!Q!@%ASETaY*O3%c%CA`U#!q5|3X5jPZKk2xGA_Q)G9S{i;F zeE3!&1Whg!y+zeI`D)Kj@15v$o*Xcfd-@y5F0JTE!3ULwzsJJ*k2gC@+oLg~$+x(Y zH%?e&>K0KLoX(54ql@qaX{{er_MT$0zo;4fHoN+k_{=Y5Enb8#p-oZ4(AUb# zNLku*_hpO94G(>=KVwP@4-uN^EN~Yn@gAG$7E(s-3qpLHDEx}u!(x@TKz3G5(JP}0 zcPC_^-J55_-6!*jJ!a8A+&?}rzR`zY@jMRM}?6p*2lLiUV=z$2&J1byyyS-oY3KnI%37TcnQyhChD9B^*j$x=*zQ$UnH!| zwWgb|%%h#)GweJ(#q)KVvS~Z}$5ISB5hM(-AJjQ&&;w1aMR|&Jef|-e>clAdeb4~; z7wYN!#Gnt@b@bpDUV92?rZv<~HJ~=SvG`sd-p-yk2G0~+|4M36Fy_{UTFR}cP~m22 zyz1`P!O`4v?#Ygem&`+-z*i7YGXr=G7z`D7`d+=$*PtvXKs$<(o38CvICcYMFvU~-kXsH5+ve`7PZguH)*6Ye{#q)Cdd>f0+$4Yki~r+Jg(GiKf~|s=I__j#RbLjS(EJR@pdNLN|TO6Xh0p zD+I>}5ZkE{znp~>txJ3CMCh&C$F0nV$Y98#g|LCpc4DpAHfAhSZ7g=wQ$ud8wae+v zF-(YH;z_YQO^8SX-qd!M=Dx>B&Xx2>SYjel-VEMX$J+ z?NRghSzPZMaQAz4hxCOe%e$>(EAHq8GnSo{%m}%a_63nOZvB-MA9x)y^GKJR^zDp6yaYvJqiaN4>8LSHP$thcLK+AI#CT0u<) z&Lc2=FGycgxrv@xJl-;VCk9lU3{1wf5Q$iPHtd;y5gsFHuAVp_%3@|1sLY2S}rI4(eTY#Q~+ROs(8U~FFA z6Ajaw3EwhB1_sm9?G_yLikp-XeZ4^R?Kp521}8TnzVJ$o-@x`1BW;gQw)1Rc8@RzRCV657+hJ-7dmi>MSM-NV(2G#4 z6HHKl|NfhzX=hSja2j*bQYKv_VKMG^1jD0;w!79Q97Qjbu-SzNuI&bwTo6a_mCG?- zHRtOS{*!1k{JgI!eU2}@;jUpyTc9{|$63Yci;Q=6!xeNX5d#O<_64i9$DD_gij-H! ztt-$BgTGO^txAALC1<`!4h#WS9>8b-%>al5RJ=t2elpOsS@!m<8*MdBak4JUkl=+| zE!=USFC-YZ|5x32@ex~Du{Roy{~u_coEmz#o9T9!eFN!=Nu^s)PJ24flrkSXB?QUx z6o=`(IbA{hLqbO2<3q(Qzc-7j1Wrk>{Jeh^IyNr%v2eNd+AOc`NROc0xd*$(K@Rrg zR^2YJpfoc63dRsg-f9uW;F@v^1(Q z#ZQ8_EhDU+toIwwWI8qxX1kqVb3N~ijb_4CDkiOuZaLGQQ)`ad2^$nCF5xDD%*dwp@*zN>R4Xj(S{(GZ>mCT*Nf>PB&K<~(WuZ|9vxxXL+%RRBEhkaj>+`0vd^m% zLRUj_ZlXtI$xPI<{NlpQevlWjt8@SG?PSDc?yzy8wA0rXeIZGT{rN%FG;2N_q+Po2 zpP#le8(KVwnW1d3)8@^CBvgYQC$>eXpwpm4j9K7MHJ@XKdHZg_^7s^6PgcNSq1N!>0l>$ylpa6Y3S~$B3yd6uMV35%ubgAAL5U0rce? zql0DFOHE8oJB}_ingudL9=k_SVYO@~BHBl4G!V$6qF&p$i(Q2+RtO8rAZ2rBTw!c6 z+phc@kVU}B*GDtRaN6t`sCV1!40HY5AVMMLKc0^Xaj+TR)@G_n@;KpOyaYj6kepxE zbl-T$51OAT{nCy&@?&Wz5$_Dj^h2QSum5r`m|t}#+?aelTPH*EmqlKKvkce&M19=WWEhBkE!q7}xqpG3?L z8e2@Q^7O?h&bTi~mAa+xK>HeY%qXc&>X`)Oxz!Q8(%*{@|RX*L0A8<%hY?1GBp z0QN+krNrQ?uO&e+`o&;^=l3UpGfcvQZbUGU#B%f2hR5a~W{ zi{dTKU7;L4URZHa_5zdO2q0f|HlR%yJ8R-x*|T#)okloYF42GeHHJOp*y>{?Z z2RctJ`!mJtTUboSieV4?od#GA!6m2epL_Xhv3B&f(e_ky{Vr`@s#WIntusUIAtnm)bZ%&T|tGB^wi zY1kIiWA?Qj1p|NHQ(NJ7w4BsB1|q&J0S<9%?nFE{%vV@vdC@H~)44P4p{@8s&;k%9 z596p%WN9cEgm6YP1>(V}JGlY+@V8}L&{%{|HhS4`0@06^3yX#Dn?PLjGbfw5do``& z840<)x~;trA8At zIDd_^deX||()kaoGC+mH;AxOrPjyWrVX(Nlbyi87XO8Rr<5l2k(jMEZdVl8Yz0e|I zwRERVR5tX8_>DXv-?3CwR>}@d$p5DJ7>hq@Nzo;y&-(P*|q2srvuJhXS(D6!d+DF`-2_TbMRnc_~Ag%cYUXxzZrm3SS)|l zk`zsjL;*Oi%0Uf~Zl>oAT!-qAH_)Zqxm9s)6=5KvcJhN~(e(3wUuvLn}ZnC&FUpb+Z?Km)-wd`ph92oVsq(%G0xX`m^R$jj*VvDD@*e|+OIZPA z4alfi>ReKl2oBJ!%`s(TG32)jyKNohzEdlk1_sMAb4z=(cm7N-VDBj&D>6#>qZLBk z`uBAErDM^cgR1JbwbkM*YnpY;3Y!1GrYY)21K))TDN>{r{mb1zD=oc=Z6MCXm?h&! zggg~xwq(I@tI}(vRAvE2ok2~RU#Z9sMGRM9?&E3}4N7UC$l!c^9oqE4KSvIue4i^Togd9;H zWoV}-?e{^-LsoR&ICvJe%3MwmNcwPs{b8WAV7oJU5J)7~z>5(Ps z>Y6UlF_L9x?7_0auP&Hb7yvhfBCWPxnsO{+131G>MU2$?jR z2u<7>S6R);jI!#WL_^? zdh`YA^bM!YQLG!`qtO>q8AJaZ7q#yi2)&n@Dukfk*?x5WDvNdI@0-DnL&B}w*bh+P z0pGX8F%kq6dFe z!mT`S=rye8&^p-9m`TYQv4rkGk9<&`2>sZ9CkFhmZnA6$ohGW9W@@aSdVD5XAs3{0 zY346yoR%Ckz^l_)eO(kaRQfn|Pi)`r3{}iA`FLAoX>(aya9ymqRa4s`8*PFy9d+;i zIV1;q(Lvadmo|DQ>V24RZny^+5AvRZIit8gXV#3duTtG8E>M8M{I%v2hT3|c>`eNv zUT(f3h-ubHPrE3>KAw56rhk2eya}i_(JtB`{w}0OTXkVqk29IMyM$dM(yjdG^-;yu zx8mW|i$M35ChGMbRzs~MoDO0BI(WeOJ`GSk?=ZetGM{WB&@ji`Z#p3`gT`(Brq_YP zN$XiSMf;;~KjI$%xQp?6Nkh!xIACQ(Is2(nIMRo1D-twam z!iP9*zPbB0%f3HxT^#P=+wxd#g5%7zot_2=!R5wVJO(Nh(b z#Z2^uxoJ=3nC&#XJ!H5VMS^}@F|?7r!`sj+pRrA->+G8z498q015Vg~3r*IlP-AOP z=QAdc%j_s~kB8Q)g5(XmZk08KT^78<9lHhDClfkKBiF0n;)>x0|JrW1>1H7}>;m5L$x6$@mVH+*sZsouPk?eX+>!)3N?jFv2;$sLwoOfn z{Cjb-jCnC5400`11S}(@%{-A8e`TBonQ{hX-de#XV53`Z2j25$q5I`IKj5Ia<|>^QlqSXTb-v!ex3;1a zMQlkOi(Ouu*=yNu(-=0(DaDi8Tv{KvO$vu%pLSTT5KXx&KwCoGAoEoGK`b$-U%NT% zLT}n*m(F_kNl;@x2K)zML}3CzvwJhFP6YQlgFzlIIm!&wfVKB6e0JI!*B**_)c@ky zdHvpaNUo$qJ>b^#m-o68izI_)!()p!49;eJF{gc(7A9a7|K_&1rAYKhSA#aY`CVtv z@k47rs3+vwJ^wpQM%wDgL=VmWJiA!QQ$Kq!LFN;}+Il)2DdWPI-2*aj#dD`4C$-SsMaH~Mehhn!k|GrnGaji3fQ_28IuL{<_I1vKFi70H_k!5<6De<-$E(@ z72}$66YX>$NOIG(sIG&tHO4J%9{^x7ms|xj2;NAECcVNTKB5|_GL`J&pUHExF;Qaf zM~KAM-86D;+#|S~gU}uP>14hQVpuLB=PGg)$GX~GnFu3eypZ%Bb#L&jz*A-fdS={n z+JJ@#A1GAhJkyGTbG`ni5GXOk8GujFg+7yfY_MePh!^IpuPsb4XE9Y$dSQvdFR=9Y zJ>@R=G5IufVV3+sZt}_ILY%Gljjctb)>=;H6_;Zls#KzfpG58bmkhP6oV{Pd|F_RfHqN$k||F= zBu6dSG-5UWp&MAAF8Nn2F88I>l-boo84uY4k}wz-#s8fjo$YX@w95>E%iREk-Szeir7RQUbWZ_Zn{=}k!!WAe{C zo9MLFv(0n#knQoTY4m|_zr=c1xYjJSV4J6%>`*h^=&A4KfVL+{w-0bK@9x}DlaDHe z4-PtZP=G$5d($x?#;@Vv6{hjvpyoWS849vKdv)h;)g3*s1GI4(bq|lYUW_h2kNV3z zg$SwPX5plEWm4)mpc>GR)$w5s+eQmH*{{$4jmcQI`~N_3h4z9PCDplef4IGdCC4C& z^q}lcx*N{CcrQY>9XwK-ijJGot{}y*&otX#<#`LoBm436GlX{_!YVP zn4@H=!)3AZG@5`yn0w&6#!CCpl5Ol*WQOKE$UB9>SK@e~QQ|k=OQ>z3VQqX`kbbi8 z*UF4GLR&D{rCJrr8P{Qn*ylt;a%P|x*i&q~ztN`p89S(HGGDgi=c&jx{IR$4>ny3& z{nS&-2nY_mzM_=? zaQX`e7ClzD%hMx@H_Xvq#PfxzL_?jgqnIb9%=GPkDXKrmoNf0t$H#lu2$*P_e%FP4 z`D?Xc0d&uA(?Yg<#h7*M=Fn9^^a3S1Zl0EY$hrRpH=rpaS1A#AJJI!L|?#x#a9ki9K(BH z58YWzwcv|^*M2?XlCd<|91T{ipg*kW?L5P@m{f2ly+V~9FLa=EKM2(iSU(ypxxlkX z>*^ploV(V-6{4#y@H>g9C3e`zLoXDFf>osTIl*7v_v=Pm(Qjf!C3n_gZebHj8zmNm zw5a$pnOysG@3!_$wPDnHHo3J68+^ymFle`Z_YaV~@{G?jXA475IEqV<$4z%}cB-JE z4~e-FL8dBB!DVG24<+8yxd*(9^jR;SAO{P8UkTO}oVLV>N)9{-*|?^jo#Wg=aaYRI zV;g8tS*cRM2}sdB0|tdasfwt}@Ml;Co!!*rZM_Up>uuy*@r%-;4ChIHF1rGpD#8YT zROWo-K=HI5ND2?W=Z^P3mIjp?Qh=a>&`UVQ82 zS^5fBF`@H{wn7>qz)+??P}O`2RdufHQLS4jUH89Q&c88>|3@eP7GRK{AY+E*5@4Cn^{OwkN$4O;gO30OXHS|wzv347O5s**<1r}0pb1Op?jxaaAD|>m*BZC8F};9n=NQp5LGJ9a zbvD&Qf4&)5#}c?JS3eFnSiYmOK=-p5KEdH`A&v38EmAmaQJ>GF!Uu^&$UR*+u@-|V z|EA=^hvoOGob@1DIduL>_DsZ09L;Pwhe3 zN!oJ&2YXydF8k;FSYpNYZX0e7CEtUvW>wg2YKmgI4#X>*4u1;^{+GaGX6dX}J3%F( zU;a@GJmd0vqS2?^kGnU9$fcf{yy&Zae*R3e^!TkT3i@CZ!{2_)P7eHB0wGL~bm&YE z{)i>*yFdYl4eV;lorLT*V3ZYB^Z4M-e2l#iysTHhrE9b=b{6b|@2rm+_V?WPMYoW5^ zKWf;=CZvg{VZeS{m@S`5pPl<6Hw&IUlX>w^ zkxW-G!*B87`OmlP0fythwKJ@QnErjaMf!uVn{zQXS#oH*ht5@hoij#hsgAMdx+mt>ybh93nG@(_e||N@+)Xx zi`263bez2AXJ12%6^R-2&g^t~lpQRJ<<6p@n%n8S5)b_b{cKV!wbMgZG;)Pa_bb~| z7xcvqtMrlwZ?g??N6!HmvTDZ(yV4H-6+=UtTm9aHJAL*xN;?FRP`Ww`%~4ebP05k8PIAqoSBr;0h-%9IxK+)A_@Dv~PTtG?SA-m+MvgEjFL zoC}|fKO+9g(z(xFo?(@_Pv)Z}0ehAg8)tSE@-l0oiKO*9RgTvPy$zH;8#2&#sK$9ef&KOjumNg4OoGS}zZB z5&U*q;n&}9xOBBy3z1PxJDP$VSz+6yA<wvIilo->VbY!=){mww{H60OVS8l*YtE z?Yp}-TyRCO`i+V->5l!8KP(#B+`Y@hR?O+(76Ip)ujQ)@yaRja))^AQl3?A`hC%DR zJr(XgNfj;l3@e^gx%n{@ zqya`!CEIrs4Nw!rUD@cjE0ayOHvhK6HniP;#H-~Yf9F=(c<$$*QkI@oDQ*6O8e7aZ z1F(V-Z5*%s7>&6%cuUoXFBxER@i&-tTe_h5eG!B#yn2Cwlv=k@O*+O;W$^IzAu?M$ zT9B!y2HBfkkDo}Tz=E9Mr|ZLz=6S!3NLV?<2O)l;F%JY3h?; z*p2o5A4aJpGfxtj{t`H^!415vKJ=Wi2{fMf}_>eR7kM7H6(4~0FQ^mA1a;2IR;~NrgpKm*E!a9+he4pa+NIf#q z&s%(e{2iU&!|&72gvR3iviESd+PZvX+xXIxUOOa0tYVzs&xYRF^#|>*(tm_VQOL~= zt{e1r0sNVnaENC20d#Hf)nM~objNF@i>BO8ClQZGu>n_8bK`Kx8#7RiQ&WId*TzPm4MjR!A5AeQ~uTX{OEW{DDc($)%9tuM`wI z#Ra`2OR`~$G?Z36{c06s)o>3QFpZKJBa;3|-lN!DCOe&NjdZksumJ@0-Sxv8$6v*6xWuK5 zG~5ZUv&mx37RKA&S0r3=pDz6R0mF5ZN4N)`3i|w%_yE;xXy~@iH1UyXZHBBidUYMs znqm6`@Vb5Sx}5yBcaYsq;iz9qMPgNh1#ioPsBFW5Ovg{RrGX0O!ftaN=~ajbbf_dw zzMa(+A37Pq^m}<{vFy*f7M&DuVkk7&s9v zWr()g90T0B;PB6;k-RG&WXUoO$F!L9^~Qjjpr4ivw4<*O`FE;aTu}ecWJUj4Mjj!@ z^kK38Ch1{*f3DjSGdue)A$!BK$5dOb3>Y|fwt$OgQ91J=p)HJ ztY1ec9ortA=@@dbq}tywxb)@#E>Vw0$lNE#nO=75Q{?@xZ_)zEphTC>h12zvTaq<* z6O~pkRV;d#HDPotRR-hYDqmIpLv=g5|Kcn4wOG-o z>gQ#p%sAG@O@Ge(bBjp;wIoxgcT|tgv(ve<6=qLtW4itVik+!1LX@cVI)|#GGm?JI#o58Z>E#(U3*dGjZQ=kFEYOanU7|{ zY4@|+=0aK{(~aOD@84glUlt}?8`rLzS<&O8GU@))7)2Gg;$3)_+f@YbwdWxl;vk`=oplj9}c{GpdZjAiR)XEdrgmn)(+eSThp~53#&ao zuqFZ;ZWWOV4>{H7cr=5m$X!fSDwx5qA>Hfg3=X+30axjYGux+iSHaId(&eS<=!_8J zq%l#nqS9>;iZADuDd9UWGOU@6EouMAm9@e^&L~;8-@sDH92L2JS9Mcd%oFvZU1@Ia z7vB?hUteReBLD9EG#^p#KdJ+OE~#L0@#HJV2X?~~rGT-#VsTbrZt%ww+P>>1LI5*L zPPw$}_b_91;8~)&)*PS8LR^t6NgYJJx)w7cmT5m8)J1VXtVxWSuKW;OrT9?|^i|X1 z)h*5t*t&~hqZiL3F^AU5d@j3#^|b;X((E#SuA)HnvMlBKZ(I;unC`p%DMXWG9+|SO z)1sz;rN#fS33lTkd65kSHQ+Xkg7eh>7rE8cK43erU#{eAjSlW?Vh|2%Wj?N3HW;I-1i zx+G@bK=XDq*}bJT9@GO+Dj$Q({{~kz6VdO%H^*899jqm(PYhQ67mAc8 zf&h90dm)UA)8bai)uMs#MX91R@Aqn@-N@4m~`agJ#u+16r4LM8mT!~ zQ4h?~iw=C}Jj0Zx>-_gEmWqQ*et&N;*38_)dm{f05Bt@Tvz32C-!*+FO6r9@>Xcgs z;2f~9RynS;u}T*r1oOa{OQdL&?TS9zllBXhbuA#n45;<4_+7?GYp1lb@*s5w7-NYL z>=01uU&a9inz0yyiv7zOPyHxpDUbXXmtuD-MsKHtO@9H_ub;*Jj$+Gozm!DxH058R z=&6^DC5+BsuFarwxqxEy!p=uV_18tWPJK^<&9vKOGOeGcI%pKU=$PDglzqyGj!O6( zdXHOSQ~Eq(G)<~hHf^q8k2Pbhp!zuotRm>X(koR4=QZ3(`oTxd06~Q6Vf)Ba*56u* zFpE}QzQ=pwu3Z#TpIKr>74EKT4VifVmU6`(x2HnanOb$e>d$s}Yu>}nJ#ZM(`0{L_ zh3pu5Zs#w-In_yr@jL`$Iaf40QZtHZ-PG|y)E8_USLucqGWM>^6RL}*6~mTge?iaw z$QafpxHtbF=+rV9ALU5dU`3=0O8%aYXf})~k7s#a;o*&Y+Pu;jbPMBlpa_3N^b{Z<$I7J+>LR0dShGD!jpxz27`P{4Ylgjo66~nKXX%g% z%%(Be4n^s12N~Wkr}tU4B+8yf^}d?ZVJ4`k;(+KNd~n)uLMkqM1EeB5@CNSW!jt|0 zmcKRk>{|?ozdEoG+U!LMh6krfnrwZ}QBz}O)V9fix4Y_fq;ci=nQavc1iAqVeY^2p z1lRul@EF%YXgj~w$a(aheG2cOSj;AUiot&a?s0;GuF7aFk)=pnHDwW24YN9xC6l&ht<>7-Z0S@s=}uWl5)2f^ddu$KGLaiuh? z9Z#lVzLdt=5UJE3I23@&hB*tnG8Lx|6s2`Jfg&2?x00C1sT*nwVK+DZulA)22r~cWWB*++vgUG)lm@kPY-`ojw0OmZ2wgl!K`(W$)ekcr zi?qes#Vusdz1KLNAcsE`NWdK<_%)tS^1RaQ-n5xRZLFj0!~xecHKsI?7pZs6GL3pk z5`0-l2q|$tFd~o!4oqCww74jRxh$iSeu~6t2h&Q<6P;T%=fesB86e{Ldne1#d@l$A z1{^tb4(E`2u~Wv+1{nUsmsmS9F-J8=BB2DsOlU!mY%6u=d_}%}-PBsCC3W5Im#QFH zWxyuP!OXGg+!#0N)g~u|1T@P&hVW$51S-d#Tc_*cz*oE1zWi_)e`x6QE6HT-@pzRP zhk|jpnu~D^d6?>x%9I^X;Nj~xbkE^W{lp7M$PEqEY~1uf&(@n=P7s!^Ae{2d*woeI zi`fqtxIMo*wv9@+h}uje>PBw4+F}TCaLieY0bxsi^`~IXv&AEh!9G5 zZ_Y$P$TDz?fRc0iIsM$8f}4RdwUXSW0cp+(Vrz-Lg2^Q&pYmsz%I@;#I{}XU%ngk= ziEkxO{rv(n>vY|+s0Fr?zVX1_%UBd62P^3G6_Z&Rl@=LK+M#%e$LRZGoR z$1^p4Pbtr&rXUC9XWJ>Z*y1tBs@sz^Td1V&X{kME{Umm%w7EYFZdHr#fd_nC{`e{8 z`C;EDwMW4i(-kf!G--oY_XB$M40&ZPN*{XiJgOzjE`pyYVi#If3$v#mm88a@ARb=URAAe z3K`ETy9p# z>>)!4`vyk8R3gZ$Nz&e=pSt%8hWXG9Oy~vUu_R}`c|YZ&jiW=uZ=Kj&iTt64oZhHH z<&}2UL++P;9iBNPYPJId+gi)OO{--++3(xw=4-SnAjgFv(?;jWvFpJv0jm>S#p45U zAIE(CUA8oB)Oj}aB%P&TX;Vxfe(9*+rUATLqyp&5mGDr`HJ*v`X6J>c^I49c9|13 zw{&-8d>|b^$?r|7zTVwKbD?%jE}m)(Vgv0+7;VwN#J5R%3Qi0{Y2u5^uNf_FNC9qK*#Rd|E*2tWe8&>A%E?4=PAr( z#cAa2UCYwbyPZJThqdnegQ=`AN+x@X|YT$_cxTNEQ}7m57|43Nk&Cd_-GR=$@!Y zpZk7;{YrkRNL#|6i`hLUb6{OQSlVAw8|QB6K#4-*l-aNN{{@2?(Rc!>GbQKcneIzl zqjW*Uw6f8rD0tU^n~s9=pMoePFV$f&L*kGpkg5wG^l(G!VifG}{cm{Lz>(`bfct(w zRHo!b`q{3pb&Gef?VGowQf_gKU5K~=Sj`m-npBxcg2pMG}kExCW+)%npIvwc8c z@WzN@w#@E%_wzCSiovkQ)pgUlUsRp%UY>;#hUm9s0SkRU*SijQ1m>v;YkDW8+3U)q zyu*@mGZj(=svQlU?N*(83|I)VvbQ`z%*2^bn>zc%V93>A0-mEVV=2~72MZQLzi<3> zv>DR1pJXf@QNOhJtVp6Ge6}gx5ggmS%p89&=UGtN`r_PiWtnm$@`_={9l~BrM5PWR z)|Se0J`RKM?Y=_zcr)e{Cj=&CSh|(}Q>IKlhHM#(s^&9>#JJ~9-uoO2s9-Nbw{9tt zqKOiksbs+?gI_I17&d|1sF0z5KMu3b%n*@~GRd8-TpLb+*ArULndlq;3=bs~JKjp_ zjd(F^8Z4-z`i=9)a)nzSBet`dDt3b4ltrmeXn=B{!0ayzkA8ir#pW_uSrQP4xe1kIyVGLWqKWl0=S2=)MtCPS# zK0X{OFA{)fLfa_^{J3a@sp#|Fnsb(c3@fb|JQlG<5)kti$7f7l>_JZ+yb_1%Dvr{T zaURyNpO04L6%TOv)aahbiQtdv>g02f2dT`FQEo>GN$t*W4gZN&3U>&r8!br_ro-fSHgRl~El|cQ- zzuatm#A7>$t+7?~N(~E_0y341e^B|7m++NV48fy5Ebt*n7kN8@6ZR#_9l9!zT27_DR9!9-zCee#gqVlY?Ec<=5QA(oze~5jMW$ts+p@sJFS&8 zqh25Brdw67J6F~nR0v$l6hoB@dDV}do#55spr`8>6!RYsHi55gC_|L~vm^uV%+iyN zs;w#ohd?Jkae{kT+>Wu7nC`h5=8@5 z4Fh9waM=xAP^`43tSrYyn_Opdr7Tk; z#nenK(;C~}_kR5B2YxK~{lBm4JdZ=l(P_)e7Z@VEum$7Gca=NSo@B8?&AWj${3oU@ zQpt$PTeXzKPE`Q>&ofsf$g4|Hr|FN)?f-5i0A1)^KAM@@-(*&0V+HE~>lYRt<j17gXJlQ4hc znrP&f?b4G1_3;5gj2n-p{!W;DcVxRZRn^!j5JzP=(``0>GP$|!PPErz>D2`9$ZYm92v6( zYh`~qV&Boqvw?yeiRi6(N-ug2NT;Y5uG4j?cLdx7MFg^q+6fXrjiPONgs`d&5ZqVJ ztTrYXzj0zYD~W=i4dNs!B3WhF^3}q$CDsNWzP)@9l;2XsKix6J?1>I1 zbok;hMF>1MY}jcNG=1^Q{J+~sF5sBdrJih$hE24Lc=a`F;O~)%?x8&KO4Q#44OkN? z`LUBItmNX!r$EnH!?*-AcP1yRCgRvDtaas!7^RTpo1xB9Iq}bg4giPey5EP*=(F1l z4Cw|i@L_3YtlG_4u+is?vl)C+^UMUZzn=;$=p(!oZj8lyJOo;Kvf+N#1TnL=6^Gck z_u1$}P3!R9K7Cw$?pLqc@LCeI;H1Fm5Mw@lcr~Or;RGF}N456*n&4n)hhpIi1s>XX zt?9@0x*IfD{GTq%bY<8=KMkrl93 z9|OcOXcd|9T;e(k*k#6`k6@DYi7T^na&Y5cY>?IhFOkKU%L+8l0wYf)Nt81$>=PE) zW)a<4u>20Ub03wyCl#ySM?Z~ztneJp_^rhXZQ5w{ojtpDH0(D|d~%fE?qEP?@*ZB7 z&bv!C0+<1Q_>U@@!t=NnqOW763skc?3RG2)w2_nF6`tf6cmdiVwbUHH_IbJ%NJ1g9 zbu;3G`Eyps+|fp;!lN~7YR2W2u-|d~J4Z1Xuk|Hn;PB7q2zEbkt7ju~X_t~%S0LBC ztQX6Jfp@CBD23GXF|%gkw-xqT-s>CwFP@wmJ@(yu`oYO!KJxwIjU$=oJg zp#n>AV)stJ#@mKg&+}gUGf1R`z!E)aMQO`_mz8k5S;#U_yu-JK>$Pmaa-cQRrf=;R!a;B<1BU3a@*ECONmV|X z*1ZdrB0I1nqUTZ33~amsNx=JrSQY_?Em1{+(95NBYFB7Xe0rlQsqon(nh6!3I$D&& zY$hg^1(gP#v(mfd#6n1vE0f*GJ^l4vfnL#t_(OfYj=s$6r3c|GQ~l6)M^S(`H3AA| zDXqSj39{of`-YFFUGB6QOxg3|^J0L%v=s$ip_`JgYLo%(V?ghPyL%uaVwS<$RDzoY z&28kcnPb^5EH>UnzpUEjGsIa_YwlTupovZPLX(o2SO>0 zcC%=0dvW0|LEw+y3nEK-CBL-m?QM)cNTD)FkY=8|g5aWZ`?yks$fv@irJWB%1Xgscd_w|B;(kLKLI7H`Z~K~%5cyhP1vSf%L?rzWO&iXBk*2Bo>lM!4 z|IatWW5TP$6j|J7Ue_*LCz{wZweC`h$fe%Q^ zV(s(`y=4nY`##(vZzy?b^og)yqSg7{XW3EYN#ql?DrEB6^S+gdY8o^_F|^Q?jxcx= zFW<@e5jt7ly!HEO+%;_WkoTK&*IP@i^2+j`e@S?9ZmRJa=*wSNF>hQNi%D!Zh`^e( zF7B%!!L?ct3=IH?@2dq{Oty&s;POUFpdkxv{#CX3A{udc*5p%tG8G!vfQ|qBbwN^= z$d|sfPwnx0ouLLj+iq6X@gA7N(kB@8?X1l|U%0>6YC}W}c(YpoJ09TO^m7fp>moQv+hf>kO_}k#87az-Zx^u2i&B@u2Fedt zBqB0>ZsY=hyODD=@^qX0e8lfq-7x&5-pkdc2nXfq`)e-$ZZn1|Ol5!Uo`{#s6D# zfnOQ9DlpXpU-RcfeUT`$nS9f z`z>t=h3_Z<1DgDz)b(07TlFtOt!t^l?k|r5&ut$|UMvIhXlpydqjsQ+`=P?j^;(Nk z1mGGN;Pt0Qo&ZhDC?xEvPx5O#$1%s}fX~kmb;0 z)WyfK8;uiZp0sN9wunQ4XWh0^^EbG9G#5CgLw_CpK%^u^l&P3iMUy@0uENU2m;`3JmqohJIqt@7I+ggleL0rnBrmV7R7NmFB z!jPbyd)0U^E=Tgl?uHB^b`9)L_6#>1 z@hcIAPVmT=2^6_Gm6wtPdZVJuPU{~3HOoZm<$(ux`G?4a%c1L)ivg2vj%nmHE zS$GuQ!bpvvK#ktz56OlO7?UY21p;nJZUPiQ1;iUE1Ocyem^2u+A>&Bvr)RqeH5e7pbIIkcU}!*2^VQ+sZCn0N-f zjBL8AcV^xpET2QzGuekdP5jOLT6`W3r-+J6P=q2|(Q)O%-5WznvTvls{MjM@Z!N%h zB*g**(rV?Cg+cecjia!}`8Fhb7^i?!2)*1(TIeAmL55Wp#?NW6K=5Lhy@}c+OpNqU zu7Y4w4JF8oA(z!N6SA$e-%?7Ak!|o9u7Wv~5Je!LybPSEfWmsQ6q`()FwYY?5EE~0 zmmIiR_HSn0?Fn|nMif}rdga~GuhZv-&=Hj}9|$CWsj1rzM+{-GRhQOC z8UInbTH0Ljsuo4y*?{EL1EK;1eLS)wqB*o_$Gof=??30uHGo;^WAADuHq^uBg| z%J^RSz#r6j3fw_q-AkoDNvz#wfhd3Z>=*qG>La6vZ?5**-K)S0;hU0VT5Y)~?6iJD z(ox~`PimQ)9=LaKt!6y(=HJ0AXb3O~f<%}Kj&0# zzUZOpE%K2e0(CDhr$41h4Bih!Y%3e^Oq1k5 z*5Q}^o4$)Kyv?f1FMGXvUu?AU=YYwO+pI#ok~ehxmiyDq<#+>WjzxOPK~y|s6xc$e z6Dnt@u-QeKOkM#g-Lbh6k*YzZ4@P^d4WFv|$q%T|qW`EY&g&{!9&bZZ7ajo`tiNwo zB==!ct0Mt6n9s;`dGX!31*UO&j4Lpm`~&qqNEBBJ{fPTYw3{^3+mF0W!sU(rUembG zI3dai^1mC^1L??;d+;}GQFb}dB`G`DiM3o=2;Ri>v;ha7tP_I2ogfu@Qh-5}1!>+d z;VB1ltA>tN$Gv57NssWu1Z;66Ewv(L&dT82N7eJY*ct-tg^KRofJ~2Vv54?B5)d=+ zt*3xrINx8YJj96IzP3RJ&F9Vog>veH>*l4rkQQ3F{RNcvWnA*oO3*3zx#*!Ey0qVQ@|!rKSxx*37}5*!Q%i6u_X&+-*EUHVl8j z<(2wTUvv18!IKJ^7%uGMK8!}iv zci^C^yQD{nQIp0j=b?1#x~ZCBAFegz&QvYj({edSknluW(Gx3?MD?QNrhfR7>Pe}> zLGZQYT2o+hz|;ksLCBr~At8{w!QYv)HQIYQk4E1q+1*W26iV|P>dKx^U2+X+A|P=3 z=yzl7;d+%*jrR|bK_~WzRPVy5e|;ADx2}XrRYs$(ErkL#9Vi|Ol&pCjvd`L9iz}lR$xTk> z=d=0^{&j-e@9&!@5~f;@k*yr)Sul~$HV^u^_KTlSIjb|Usx$qs{O5PKu6%tL*eznl zl)SuPZ%)hXavh5ZArGVRv{07uosJLH71?rl`qHTaCjlvY?yd_J|G5MkBBmvFEB zHC8ekN-nIV3M%xW+8N+tK_9RA{kmnOu&EAYRCKgFc-}p%%d1Gwl$=#_4+e;_t$&P} zAvHEYI}R*>NZl~HeC?NT#?TPJ%VfY%`An-W@*EER7L3FtbLvYW@0@J1{uwrG17$j4e1HAn;F8b2K+( zNJSQ@=XL^v(N-DIxlz&bbtjQ9wtD zysV<}sQ=k^eY|lLv;tcJF8Ht#DT<{$=5`G5`5~@MP$UaQAu{H@Kh!3Y=?m?wgc%`pt`IFPoa}$n>a=C2{^# ztsRy{9w3e9AkNuaN|?{FX@j@IBZUOwS+ofmSd`=UDhY=E$E_W{-Et>zitA^IXs8S* z`io{r0B&eo^S>@E0P8Wx$&WW|LcB5ESKb{S;qEM903h}OABVf{ZqpZK zeUSLlQWI+3NrrJ)i%xo_x_-~on(2%B&z}A>#^4O%xOL1`v>y4zsp)G3w&j_|iYMz5nNWeDM zwRKlSV`BrrHXR6TK|pt=O`qSX3O(FicPasVEYmHd&B?<(wm;zc5D+V?AVu4bBr*p= zQe|8pHp4=SL-=Y_$BHyBX~xDtDc>X{7XX87$L_}-f}`^UA-pl5qCQnIkPs#ndYZQY zS}w*bRo=b8tIly$tWh~&vYHGvzi}AcquV{D;)kV0rswC4x&4wBDWFf07rVV`E;~6o zh7v$!fQmY>kub)*9NC{o=+5d~tn@|t!|xKcYm*zAX37h<8iEaWt~tODu-cGeZ1s3X zGSg3L9F&;X(n@f`Qx=LoSK80IJ3U}jUz|&@hE!Hc&OAY+>^WWvVlI@d)^$tfrN@Xc zQdH0&=WMLG2Kk2-Vej<}b3xA0_Dwp~l+p=v`X7_feRHaC>5vkP!xotiifrGU%_e7C z3U|x@7-a$*`7*~J=n*elJ_4=>~3?2VVp?P(ifY*?o`zGBfQeg$S|9-6~=AHwAvcaOi zd?8=+Qm2KL*58N}WWs!HEA|>cID)mv>a_0opE^BOWr#t99a)*UTsCyE~uZtt!`gKe21N0@UFTewXTGAKY>P9=>ii{>#Ie zkG}&t!fpN27MUM)Ws!%84pg{4S+;^1wX&$9pWn0P3PyZA^AL35h4x-Px-ueHY7 z_(D8NiIQ1ZMc&=Pj1{Do`f)kQH{4IbGwlS{{uBSHjTc!5{0Mc(^dkaIp~PJUS6(f? z7}97JzKF;|yxGyKh!VYCqd>kX~N` zb%zD#xj4T9o#>u8eV=HH04O>x|NT zHQQVE>Az;FQET(w{}FPW1$MvRffli!v+>bngK4>8r^EX9B0C%bU9<{EnY4g|Ut1V8 zY;`fTK>?^#wvNVy*@Ge2hA)?+Id=6Xd_I>RdcCm^ocM6Az`5)z9tm8fsrKZL+iD`| z@PZ`lM_-A5g{Pst1+dx5v5ah|>xLvq(&Fd|2YtjCdsYB6*+5?x0>$IynGt9mV6)z& z>Ko9r9SG>_7}!hqVA%I@>x$y5$(dco1djzWBC6li@3L8DW9-6w=t+S=gj?gd1))nt zqS%vBX;vT<6FYld8TM;*zovGVYu;!R0hA!K2(Q>f^pA@|%-N^zpLaVjj0^rXXaz)N zpyOUCc5sk$PXBsl5!1lq^<0nOkeB!VYqq(rv_<c7bM2o%sRw&IAzuulVKnYKx*_`u2&?hWQLwMv1gnimN zUT-fZ1!nWH7VM+sB@pjsDQ=YJcW9@t{{3isoQY^hZxo<){HgjdAxxseV61H%s)!Ej zZZWn2_GFA2pqLaWo(N@(CsU`l99;@K=E0;sH}E`$cDP$}%%5>V=$$9J1ke>lx7Ek| zBA7JyTP9~N5a{kgnMLa8o##ztaLcA&qnr^CzJ~V!q?rbag_jvPzSJNj_t8#WVSdv{ z!4=0K^~xiUXo8#eBE@S?W#uv&v+!GYcm++CC)+Qmfhh{ zDxD?G!XV~3jJ=)-xVJN!w8mG`*N8U-d_$*L5UDXvWgrpkE|oF%8HPvy{+L|ycV+%x z?1!a^>C`XQ9|u>v!b`WWZ7M||$$mF>lV5x6b8{+|DM?RmnCLw zLr0Pyod_~-x6l{s(KF{pRH@{)Sc@&l0H3UZT||(cP0Nk8^qsEafB(k~jJ6R4(oV&N z?mMBz&!3+fOCg55s}5kPM}Qw>#6vQ}Zx`L?E78i$S;QR0mYSq4E(Qcql@_(&jrN3j zg2S4KPJWP^1%#0jcSiJ5H?pSdFEvg?fr~6mV6TYC0Jw+1a1i%r!{=$?d3uNeY|lU; zG)0164JBa~8Tjz}hG(ImBU&tJObc(7w; zv^|^#+EjaiiN<^0ki@ogn4$&Ip_rH#Ai)p`}dfSY#*Q~Y4va&*6e@r6C0($ zzNPkVb>Ye4r6TyMa`ElzqX;p2Ydxp@+d?aEhZ3-0O|& zczq##Q$=B_I6ps>?dHVAfN4vk;;A*~So7!X276ZC9r@niwAxZ#+;UG!yL!1iISPm+ zl2$r;o-&mHvI$?5Y_l*blCfjOK}Web^e4s&et&{=8FW%+q8$d?hX7?sDDsLd%}@P; z9}DCd?slhE1BWjGM3kbXU}b3&_$TKQZ*XCL*>X}}V`uoSh#p^^>0-bhen3yN&vb3{ zV>BIbJjXbsE`%(R^-k?1qruO`2|pqyJ3VKyWgWP;qZv-k&eDJZWN52aqjv}XizueF z8R-`RK*&|!HT%(bzxJEww@huiDgQF(n^s%nVKFy5_-HV?qAvp3+BY|k|LAx*g#?4h z@8YZg?AYyDuW^MpN+x683v5yK_y1l{Gy}0R5T&1wF(g={kE-mMU>}SxDC-ds>+-yG zSLse~1dvH}f!k#c`mX=4A9D|ySQ{+db#+y~(M3lpu5Ymvn@Iu|gEJa0l~V6mcT)kL z%6LI)*v;Y%RQ5a8&`Jz~0z$6qW(;bO3VQc`xu2n%7my8}-v5}kaoSso{3lbj^=yji zqc=qJDaGaR1p$~^``bFra`4(%$wvTk1m7h1x~^Q!tZD8Qxb)B5Iw`KRo)*^x(PO-@ z*flLvm#4G9TAX45f{*pu1Zd?r%aDYVS7kFs%37`fQdjZbfcw4D^LnU26|6_-M%b^x5Pa&VY*%6q2#sph&0IqgxNFI$_tMGx>q4i`U#J$I06 zGM%ilu^1b4c|H)`33^1LVvE!c*-9YLJ+6h3uYN9LsELwBJfM$Q!#uAPuCekoN&*B@ z9r^8q%Sf4;7DAyVIW47`D$Oe_xTWi(=+&jU8L1GU6=e<2b zihWKt+m2I1uxj_6kp+SHD8YXzw+{z!fuaUcH%?=&jn2y~D!g<7ft=mzuE5&PK7 z49*t3$=RYbK+6{}-Ks508w>)DHe1rlId^stY!JGyoP(2Q?r4_@X5km5N%}`*$URIB z7Wy3ufO6+@lEj~Js}`;@xnF94UZ%2>;B;_CrU@JkV8OiRDSKu@(`vfv*nfJVN>ewJyL<%j!tjdTSbHl0qhp7I+%XRMF&9RHt5{lkzvE( zSx$&?xpHe0Vwv^t_T^3(7ppTLMQYCUwb3%Q0&m16McSluPB%|Xazp5io@Y27w_eHz zngmbE59zxe99V0xMn(So$hobY>_eiDgf;+`I496?F94Q9NAM!x-JuYeZ+cB1a%6X> zPh0AXrO3YEx|08rP3jg`n4a1H0crDk`tb!)ne+{5d}oe%byHXidB+opRtwyX49?mz zUSIkgc(vqr1F-FmYoe34IiI6d-G%S?mgcq1)Rju3_!`ZW z$?L{d1;)#kdHsBaC%D((EHafxeQ*ZUo#_R1+Y2F=gNvW`c1FZF-12BKXk;0@F9ezT zuGMw!+%{s?)H>+Z*RjCdQStZd3~p1a{biF`lzVMCR904$HeKHj&T+vt2jCP-p>PLH*Y4Fv=RMUJ+QIdxpt-W=BgKse zs`5)~1oE79)o48DQQ=c9w9aNW_){)tTYz>85-pI;V)b$pezjFc`$`%STW^MBq(1`x z(-<08jxsYqWLIa)SdZu1co2+z761Y`Y0*fC8c>kGc-5UW+qO<J7Kd-nL36=L9hJ-upji6podT^q)DB zPYkZAi=Qc^0*lBOv(Ghg&N|0DBZ1Z9E zrbDn1%dE@(zMViPgnRvWv2T*_os*Pj~=mzH(%Y z6{l@_0w!sk;+M@H8G^oUEB=c>hx>{jdpTy@+h=8Bu!}bUcpP3ZWN^Y$hHDqCDe`bd z*!7oA)b7XTh3wIvRQ5R|aVxl@qhn3vG(>x{i&ghpyh*D~&B<~O;>Yjz6r_Eta4C;+ znlu1J&ej+|VuqE$B`j*WzoW4P z2xMr1PPg8}x#XnR6+JCaf1?H1547LTo^ZjxhNF%mFdLed=S~DdgzuHs^)Aqf@avCx zR4ndz5Wt<{nE$77`$N8^gqB&CUDrRkAzV8u>L*E5BbJfyC# z0p4kY{hfO$i06e4-bYsgrJ8~Qko@kr$?mChkBueAuGd|+Fzf>ii1q4&aIk*pkvBj#v=;`51KB)jXUINs>z(-%GtfM<%<6&IZ_5b;IrPqnztbQr#Ka!f^E z_k2@dAS6>j^8JGbs>;CTMlMvXP4mmmR7>p>iE!xhx*}ozV#0}VYdD5G*IkgpS%7)Afv^FM2xWd$M#?{VW+3V&eTVA z!=)QMYdgb^$+kbY3y;>H?{xAJJ)qNfnnueJ#>Gl|{w{uM&st+N;Vzv5Q!{|@T3=`FHzu<_e)!)`VOWK1tsyublzC&3hRF>?YmK<3qfSSrM`5YFofu4<|p>3;B~pdHAt^TVV&F_Tp_q2eAl zL#vv74#|5Soz9{$NZPoO(a8Ut7&-E<>T1n* zR<7%0hjnj3m_M5c9MaWh7u^ZSC`3d`L_Hz6r>L;V_;Sr$jT+{rday=8JrM7ft>bQ? z)c+xfxGA&2Ii@tn_P$NG_J#d=KrdC2ee{-XVBa$y`pPf#Z;uW7Q_^DSU1pZO3kx3_ z4_quYhF%(x(8>f6q?N$ZmLa)8SMpl#LTH+yuSd*geyErI&MbAHVCwv{hEfleL_Vx2{fKRI7RoAY&Uj^M}*55Xzu zRfC9MR@JI^;l0tn%TNy9Lruswx3+Sb`ItzQ0nJ0t{_tUylVony#qW&htr2IU*)JI9 z-7Kyo9@t-yH;U2?L4@1S17{&^dES(Qyh`opHXO+H9(u>9=pxL>KIz!+g2MZ?McCv$ zXMxP%Uw8SUo8{H7jl+>1?%}KeZ2tW2Z+e9z2F+s@l&#-y9h+)!|DG(>8Yyin$1iaz zfgznPTg;2>qHn&~R9AtIPwQI>Jq%9~@>5%uHrf~H3zdtg5i|I}=+KEJCY{iB;}lz# zHb7+Bsp0K=PFI z0!d1(dd8vMThk=H7Y=83Vzx&Ac1Ee}^XkChY#OOQ(>4jo%uZs@T;T9Kib)6p^s#2j ztmPs)ZtE;FFbh901&)Axyoc~b!cD-SRB-{qwze$RTVm>tY-6e&{<{#Ibf%?_K!D7C z{G2m1q|z`#exO^nEaUtZnNh{+hVQu)nA+DoIHhtBDS9vfOt55{$9e&i#0>K<)Ws3u zksNMVaUG;c?giijMRrbrkeU_H&8wab4W>8d!y&#!r@ejNTydv%6at- zosj-!^_rq{1yHQ&dzruqPzcj2wnYXiwHy=WnQcjZ2AU~yn0ZpnZ9%*&m*fusSMW|e z_(!k7eLMiwcHweNMKVzv$KOj&JGVli-~jo8Pbe}`FCc6b&p@q8LbK(DNdzv5*)a$3 zk@VeYwY7P75V)mpKz~uf`c9IOS~fIn3q=82SJKAaL9apJ|2Y{nKmxbN^W>0WrMJs? zP1{=mKWmxexEF7CW~q(ED|=Gko0wjT15)-!o9u`O&ePZ=YcyaZw`JA=j+&PT7hYHy zYE^PL3%pdMVH|o!phomwjbHZy9xEV8`{Xh zbZ)O1%L*#7$o1wE_ZKszXh)EdLZBGVM&k8UlNc{-(%`I4jm*AZRXfd4IXWNA^#2S2s2 zrkOzL=X%dnUb2hiR+0`x__Zzt&!4rU)eIOyVDiU$C|3Cp!9GW1uLXQn$p_MbU2=u* z$l}jJGJS$iKed*DAHGb`@>(2#XA)_$n^kHHFpvzTxUN3S0 zKGUEGuxmcTy40P{vd8kx7Og=K6SG&dbOMKE{R>n~GZ4Y?% zWaiAq5Mw^l^-m7pU{oU(4BrdNEtg76G^O0^5AI%vLK%taGeCq-_g!^LW@FUlEu9(H z95hVrr53z#o&2m@`s5Bh3qf^7e7^XHj%I|LyN>c zm?rzcN~`CHGb5lS!0E0|S}r?waBdW1-(^vkRY_V~`U3`_qNY4<0)*b(H8E>F0DD;{`l~-r`5Q1I$y5AI49~J^!aOq1T@u^kW z05Qdq#5?>g#Pp=dsuSjAAIUX@3VlwoPg=!`V(-8)pt%NLO*C;)MZ>*4vVj zF4zZ9Ar2S2=x?hCG>@Wd)~|OzQAst<>~o0cw_@)B@g8*=P@l(A81xWY-dfLu=EaG_ zZ3Qo+NR-@|fCIIE%2A-Qu~009R@++EVWG zp)q=!bV-Ysw`$|rkvG|_s;9&#__vklN<7t874?sNCr?v0z}eJduO4<&`P{H9$}f8k zthky^#3-xUI{$aHODJaC>Vjr$v|ahaN$f)@d6d(e!FxV3?Kq{cEAVI_cXo29<+=Vt z0JKvyQ}t|-@tT3#`_zSR*)d~K--kihDRU4Nd^LFYy)GwI36@EM9&xuMtG8<4y=7<6(BY6@~lug|Y zD>ZNs1Rv_oE@CK(`82b-;sWEkCp8$6G=0-uF9Kj0ebpe6dD242QBc#ro9GFP51Z#? z4k00M1#l@nzX$iWASP$`v$L> zFa9k=Y0EO5O`Z8#8SAw@(Q*5_o`vh+En8bPBCyniy)!_EkfT`g%`(uuWnK{w!QMnb z*2;c?pi&ps)G(~_$zopbhNXO+D83BfJ}2PZ(}vV*z9Ik`U52J zxG-1p@tc)9LA@M>cRcjkwZmV=v_&V>Zyf1bg)`TeSPKWD;l5)#tf|aU`?p!Z>;|+% z`R%c^W-Ecx0g=sJ19ogN4Qmu z(2CU21~>A}1Ymh2G4(C$wN_Mi(6Ve$9~K`$>5X3SjXb?tTOLIUd7rY!gG*TqjRz5| zS}oZ5f^4JHGy(b-$@0Tg$?2&CwA3jWRciWYwA1Eak*!XggCMJTZPE0ZipyyG3r==) z&?g|)R<9>1TG>Mf?GH2uL7*F1pdOSO*uObjggH0y7SvRLd0`qk! zD>XFu-lTLyCa>}l5hAcULNE^G;9Az5Tdb#-&(I^wba;@06P=&S0+%xG8`^t+tYzBH zv$VV(hHKfke-$-uZWNZ6-%W7~1DzsumU!AXEo6a}Lg53(PtK`Bb zWP})brXtzF(G884iT(B>6I>`@n~>b|(+xG+0F0LzN}`0RQcYKh^i`=ogZr1fYZ&=Kp7?wnWk=MucItW&3U?e5_S z=Fh{q{GeaaNAs#bK7ve``-=F3AYmYVmp%yTwA~P$Y;Es1ud=mz4!65K=X(^zTVPZ% zn>@n$O>v}wT;l$M^l&g#FUB`*<_m}SEG$M+XhisHkd?!(>kOa<^j|mNlQ3l^(N(h! zz!IN~gUVZ%L{{18D6YlsqI}th#(QUjTcIYWep!g@+N3K*O3PaSWJ!CVyD~r@IQ>IL z$41BVR0e%qGoBcR8$a`@aaB3Kf6%w2|6F7{DF~CeIK)N`qmxRV$buH3<=7X_;Yur_ zBq=JqwNv|1{!5OZeIhk&m$a9)sLk2xcsBG9T(>FaDDE)_Z9GYL6`enW* zqjqkyX@AUIz2PE&XinN%J28 zH>sWA2kFSt-HVHh%z!u-CRV$e{q9k)ig&>9MUNj?p&H@rA9G$PYg26nDco9Ldd*W8 z7r#}QU$^*%(sLcdp@vu^`grr!q7T4M^xS{A8s$U??RMG9xC(Pz#8%nS7-ixOBq9#{ z%u#nVZ%O{x>_za1CwD(!BV7$_!te3W!qj~oH8Gmew5DYoUyQixFGcKF*$2m6E>Q!( zO;+Rf0O-$+PyEs+2NQzLLIL3`b=?8Avu^CxWaPid^I4p_SDdQI&Q!|6N82Mj+A zg-^FCaRi7Yb170%32N1cR>T*f(trr(sm-k*u7?s7ae9$yLPa7?+WSzAMpgOlPD-Nd{P5cggz4MrKs^`5rQ0jN;JbOft}1N zH3KGe*U+?3HxcN4by9jw&oN(1w!zR&-ufb|l;{K^L6+n#0oTt8cQHbpax;B?rZ^@z z@~DuzwPw#qh78b~Pqv0<7H%XMLbcU*MnqE3W8b4tV8UZ}i7}?%=@<-YG0{~o1Y0OT z%Tkd4;X3t4waS*FuzYH)F*~un6m0+beK3zghChYtP^rDO-!03Kx@6YP{1*#BjB_5X zNb}B)h-)gOXG|$*p>N$j0S)+$3Y=}M-EuTcaQjo4n}Fp3lSur0x;Sjev0XK80!H&X8;?t>y0%eQiWS+}?6Bj{!3@%g`UslMRIc2jA>r2@UGI>0=0a%kF8 znEuuP{Mt{QaHcQtYz(UWiE5j1Quz@&xyNCB2Tj)oy_yD*uZ8sPuXxBc)EQN)KxfWd zX_nS>w*EvHM)y!n=UiSWn-Xy#6k~UXYkCC8lQX?t7#oBCekk@$^d# z*g4=BHx8&kZg!>z(nGQU&Ge-4?eLA%R*L|)OjgxPpTOjf3!%s ziq9PdQDTe4nXtRH3VkldF<5MBZBLBSH+Jba#KC0tkKJ30Q(8R=%{Sha%rPqPys+zB z1$7Y3p7~)rL^6Hqr*dIVC29xVyIy+jawvB0TC|6r!3gR1;47n;rF~Ot%@}?u_N~c~ z92P0l+=@N0c)g~dfiwx(JxHtMg(hDB>FwF_`7_(!u-JoUQC?vr&YtLPjVYQ`UzAvTH!ahVREV-3RVM8d7R&vmoLM zH+Y6y*>SW5U}I3Uv^7%?z6?SG1u#wmGr1T*r^lP;X^vM`^*zd9g$xS(xix0LjG%YxwPx=q^+_hxzhJ* zbAjI3!?(c7mj&|`2Pb7mQAbAv^b5qnf11zcF#`Zb{4aeSzPujVx#bfvbtM%CJAp`B zz;i4^2g?2cX^KE9UsnWR1#GbYW29TDREu@+HW#nEv${YQYUSI~2$Vy2Eq1C87OO~s zemy(O3LmmP zUJB`jZ`wP;Dl0FTft7z$e=jOHyeJ-mo%+`en23%RK^C8sxFe>evivgn)GhGSLeEJr zC#>uWA|iZZNRxC960a%UNecnbxLX{A_ftE4%f+>YwbGX{N}0oiL&CoWlP?_)4In7~ zt#vdDujcVu%7Lu4nQdqC8B)MDE(t7oai7R-$?#UvJx{*y$OM+zhT>xxK|Me10$dB0xI=SE(Lsqi&+X{seio>ICS3LB4qO!=U< z_2*3ho8GQCGAYMkDnRkPs1FjILdnr3s-i#b(N3=#0nr5yOuZk$*;C^VPoa~h92S=~ zk;+!rBu@&thcxL}`#>J}QM+ry)8dX$YtK^rhL^lEgzF0-`9IVS3PFM^pzO&Ot0i)Y ztX+=07IlOrSqNd8VY^{9#@Bi!%9r^^$%9P~UG9ehiOg;UV>&U$zDF2#|8HydacXr~ zUGEFauJWPDyy(M9Kds|vm{*y~hsAV$RsNzB4^!=@I$xJ>4w|k7j*KWZZP>o>eOpK5 zA_qBf9tQ5}ts3nQyT4xcuLJa|-yYtf*-cB!+Mu(nuqZGN_vPieO8WYeQ%1G<@fIRF z)a>u^*O(=EwIBaEE7>Q~j7~xJHciNW{Uzd*NaugO!S*q=k4ty<#}9*_HK>GL$x_#( zzvD9o$5$EMgOb+qL1QH&^<gzu3&&e6kZ6utR^Dj%X4`>6=!c}_qRKk@DjNTd%z$LF(eLO z@lBIexqQ9pZ^&Tw^7MzfyMEuEZodV2A0lMY$sETn2P)cZhB=+m2)>=<()6MBPBU%R zC)T$x{`V8)tcs&ICJIGq@APlNbrBZ(0d2AoZFb^YslUegSyL#iCdpyyCOXmzK^u2@ zGT%KzXRiiQpiz58PUSDYxvKbpu;{u*o%*cDjmm3|+!t*g{!p+)CojOLLdEK#N36(DcCGfl?>SEpUQ8e}^{1ad>1zF6exbXw-{i}$ zeDku(qfdy;y{Wt{uJ>vTfQ82o@3v>~p-jae2p-#oM~@4a7ov}vpJm4Itx%gD&(H=I z!tT#1UsHKB*H&YFvU3Xx{8(j5-Bbu9k?9t&#a{oM^aPbW#A$Rr zIRw-T-m!hSWKq{!a72kT-aWtnW3(zK?#r|xcJSKv=-)a$y>j_rNY?t5KgrpST>!$h z&S-6T7(7eBz7wiGd>rUKm0GsbiYI5fWdA1_;+aPErq|um*$W{c)G!U)-Q5?!H@fW; z!YOzYxa(?2CWFaiznbh9mZ^&U@}HOFHKaXw#&YTK{g`i@OyRVw%*}JoCFaBHqVG_< z#|trO;X$XR92#k)G4J!Aeoj@@5`%*2hIhToar6D>Hu{{7X1#Zi`~eYhju&cQXl8~M z4{JcP6?hjOFaWXgq`uUV65K)fBLwP{HyU!@3`ApPO>b4A9}47hzJLaOR3zORAp?d5 zU)O0k^0L?Vy?omA<{1w3#xC2obzo$>B27loXKwHs?_jUeTNlO{&94Gsa;-`O z?AF&3GLT`^na4i94Eml{Hg8i`RLp6G{SRoZ+_OHgB{A9756_%(pt@XtJSL`jboC;- zqUFg#H?QZw0aU1NK*p69>Lu*l11e*vw^sWmDvr9a5bdL31zGHEzoM7W0?7gzFi_kT z-R&@?gXKOx?1;4yPy-WD8q9e>luD=>D_C)hWkgcRa0ReQ4=PD%7R%v3o=8l&6sOED zzD;qu2P!P#=sd^X!nvMk z39uO;yEP}kvx90zy( z?tQ2>STcdCkD|O(4n2u%pJ0_XDiB{wH^k|l!Nw3@|C|Z^rp1ukxW$W`N-zEUaj=Gdz3zFsHLJhzH zov3l))HBbrq-VSSDQeUwT5?l#>rn;haqQH#Bg;~k8Bx8-pd3F|grf$VKa@ItW6HBn;|3H1xA&*unXVyUyZqm}hpT>;#d{*6t0 z`c+3~B*`RxGvFgg7B)2J*STXAcN3;YjgSu(Ln$*>Cebz3D(DCGU;Fqm8wFf2qrp zL0f2w##L{wRsi@OwjUAl+Kc)T>7B%0Jd4;pst~HwIZj)NNWXmPNcpHFXF}5=_tOP& z3W)PKP0!REM-hYtHNPayW(C5pT9K2Zm2fx^FR#>as>hXYJca#>9|w@2EO(xgvC>I* z=x*ykT09}~tBj@sJMrVB#oArBVMl)Yt##X`08IL9;=k^GDd+PV=gHU{X!sMiF$1Vn ze|Q=m9L@2G*u`9J{~li=Hfa3qt@88l1X?&i4d;X$SA?}5dK*AV@Aoi>;9%U5z1g_o z>e(HKO86z6==Na8DR({gbtHbc**z%DR9BbDL z6V+$t_+@B_Y$9VyP3E!PJjOs{);b$5==~m}WtZR;AgQ>QqkZ~*9Nklq1pT2p;?L>m2Xsyc71VE3T&KXq*67Bmp?$?6Yg#nxLe zIG9yJgN9T3%yWh3DI7Jv4cTkF!vM+#Q9c_X{ZALSF9n^As;GXPevkC`ss+wuCSPhH zbfyB>PR95R;^a=8A=bCvY7K8%WcK-*u%exGj(B^g0f$B1g(`c!P zOTpxratFpmV-KaLIqF4p%VBR6n9;UGtrQI_HVAr8L|-~zGIEv0Q6qe7NGtrDdGyi8 z{00gE1|8L_*46@3GBX>q7~skx%=0+eiZOO;4P+Zi*w%+JzU9ptpo-#a1y01D?;$)Z z+IGGks;vyJOt#r#IgJI>rGIP8Z$&SsFFeRGTn0yWrfNLdIj&@)_aHe);ia*P3Yc8s zk5+|zvq5^g*E|e}cGeTsz#+jN^DZZTrGNZ9d&3!uf2trYJYtYFkZBfMn$|iGoX7zW z;(hNU(7??q*<&js@|6-_jh&c?3>$om^E##l_7 zCL|2kmM^5RN4oXzhvE*vy+_=VGB#*T@h_+qKlL*uRXy0e6~2>O6R%uz=}->eRHh&i zBz$x095UBT&>D8qmJpySy?w9V{CELqbEY&FpBn+;Dgq{IQsZcYq#y>8^JO$XFz`C(`{)iIWEW}M_Qk5$ z!R(tiTT9;M7ajVrTpMd_A)g0$ba#4Qo~p3q)vj$yoAyf1tlH5e*wAUQ(uh4!Gj{6i z6_NZ(zUc%uQQQ`k-cUh1F~0JL6n!}2A-{z|!O4~=#LPhgHU(s-E~Qlb4*PS<_VhV% zp>e?3AWZ^p_MZjtAEx{6X>Hs4Fz>;(YT%s!S}EUmcY|pgC|#_)7U-y|(!Q}EHP=cB z!lkos@i6F*M;Cx6@I-%3I)HtUc2^X&ccPNx)1pw?t4!lo_Xd4AH@#nwMihXMepqTQ z8YEiu1cmuK{i?H+L|$a`Q$e$AqWeG0q2VBAo6Fn(Uhc%k!@Nc+jQ<2E&j0KM2p{nY zY9;S=67`3iC6_LprEwthxdWXYXc_tN@C|-GAWT++fD8tDz`JIx7cV1^OX?p&L|?OP ziDH+c?Qeuu!9dsG@xXUqcXUtx{_lTQ8OEcn*P;Y=oNAC$(2#}Ct)-}Fm zlMwC*&iJJIL__myJ0~aDC?u1hcd-~Bc(Oi!DE7(~(H4x=h51mDZ&HSFN`TQGUHc-s zVEyF5GdM>Iyv6~Tn7ca!s4&993{4GQlkOiCtjOg@wNeQuYz8TzEE6JmZyk8)J6T)V7>ygT?k36nCIv^Las7r3NjojSi6TjhP}|{XGwaY7S73I~+}boiK2a|E@MEDSk(BQ)XI9n$1nN9cwg!MIggvpx`5 zH4p^>3qhd3KA<7scKrrV&Ym2prc|^!{jr~fnM~??SNl@RHb=OJziX=)7vrR{fU|g1 zZ5FY*2xj2_(dF=p_)3h|!Afg)x1aKggq-oO0j^yrQ))`Z*oA|2ljYhef~Il{Z3vOY z9nO6RUaZg$dL{SD>l+!fk@OI3Bmqw-bMykLs@hi0lSDTHWF5h+yEQOuE3^Abb#&KNQA`; zYTx?tiNkMQK zm^|PbcZ_&W;d}#?zXXa?_#vILNwKJXOcML#EbboZt`aKYS7bZj985ew`f-q+NdSk- z{<63At5z_{nDO}E-_<_7zp>nanO_mZ9jjvH8*T)7%6&f>pYhHLwTmlR-5@}Z5E-|p{P+^iJh5s)i)~?^S!zO(Y$t+f=>|`}}YFq3fsl4M^ z(@{Feg`}noPx$td5kRtAR_l#-r!(2Ww08Ja^>Do@-U3@Jo{7F6$%BoXl|0k?Pz=z6 ztmr%6Gojaf{CkyY9@Gb$TbDjm=x|BdAi~4?WN`8xcMjBn7j;_)vrhf_>0Q?oMrOm! zA8NG6{`8#d?$eR?^|(z2wgj5luQ|N!Tp~cKPUAX7ws%^D(dNQKsP4R=uW^E${*nC_ zvAiAUOp0igI++x<6ggx8lq9KoiD2#D^zJrIZb|YQGzka){nJa`uzBZMPrE*HVD{2d zZQTaZ7;W6Pk6r3bktI)Y3ee-fL& zs9*@VBz%Fp)E zX@y_uUoRa3(lw$zq6nUGB;OTguL|q6D;=`RKMl$ekoyN)(|!5yprF3YfBOmTSGWKyb<| z6qh$@XVA?gMWS^uoVW`!dGnjWAn%5DMe0>xR*~M%<9){;MNe)m4~5-iBH0tx^syQk zZM>|Z3hchatQvbbNsA`@!&91P!7?@C1+I;1QamaQ=a(J&MdkX}kz+e=UTzacVTzP* zrBWWp?wtlK<|skqjrrDNTW^|`TA0oQbGwO3`2G>kKxW(4C7XJ1CU$=ScsASKw)qL= zGNr8tTl}?wyM8g!q@zR~TGW?FCO}{Mw`5i|VR)A_;f~PXb=LOQInVDnj%~^_x=M60 zphkjS=U0K%W~1?S@g}Z*=1$EAcJqswFx~_(90mP*gcpyl_ z(V$l4OSH#BH@)WGMF6o@UfQCIUKWb-@ouK#aQ-cIS?+$x<&A}|t-vAliG30TeG`Ph zep;+Kle|15OjRj+Mf9O!llxH%kcMAO+S`?7nt@~X5He2*Foc) znILr<>xfhYzAvztQ3+cs`RFx}OB1Fy$Lq34<0>%g%&yoe^BReyJ(LInaez%cceH}( zi%RRe?o9_J%J%GX$Gwf;dO=@-3F4)0zEp$uWldI&`=JzpXMp6^>Wo-9qSJHpd`DE> zzMajKwH|D1kSx)FpH?cUa5$Rif>N+(DvezRbvY2ydF0BXVlx;gh~?W(ERiNsYS@u-z6Bc>dlyDj5$L^Rg?dr zJKqyh`U3&byvJD(cRb$lLsgBvnX(S_c`Cb+}QW%oEo`*&3<9$7(Au&w2M(&f&Hwpii`ld z(vuBWOt!K-dmqlhx{2bRUV)dj&$s&YSe`Y$D1{8|VYz#3TEvNYy@!L67~hZ?)Yhrb zo5KD@Ym=K1a8X$9$#ap0`AS-ORZ7_C;!^FMCy`Piru;9sX3}sbpd@pBk+SfF>uIRe z4}B|?_X@2NMO7!d$o*d_lP;eoYH~zFx-M)A6kEi; z332nrrz(rub5&pY$FeG7?TmtY6xF1jI9;~>HVNG0fS28sDs^ud1*I-Mz;CXB1CIcw zD%nA_wyA|N4Yzag8|9c#b+X)MHkce~dWUR;%aeIO_{w$o=LsnPfj5kx_DaEkVls!UIroF)hYUU1aqM3laCF$Bdp!p z8XTAa_eSI2GMuOU&wk7V1BopC+vd{KNr#F`m{V+;vb+c6YQC);z2!0+3R9yMev^OdV6Dl~f)bTt z6QFv}<$)ljSggd$zHh6N-CXJKmtO!5e}jpK$u2E?o`sSB#SfJp``d1=!}%&2i*7_> z#Pg~pO*&7EFz11v6I_JAAmUK7dw3#aMq2u}u4#bC?AhjVTxh5i_&;Prn0NpMR%>@^ z@Zn+`3Lr^It z98aK`{Ze)KMhc?SV9jCL`$ng(0XO6)xQ^Cb4W-l%rClS)o_#Xj^DWqW*6zLa-zWBJ z2ef9F@O4O{12z@(>g2ZNN2h+(JRwqk{GZ~Al~q=rGp<3RnH}-0azQAxD+k}{CRLId`Q2_t}#x03;qgW~5@hp&7 zn}GtEQ)V8Wn%4(23pV@h9*9K4xvWL<=&smrJIF8@}2@_tr$~K|I$`2zm3taGx zAmlYh&#UCb>Y2Zl1@;Hj^bT6tT)K4pK;hE(QGJ1^(M(7F`YnV=`YS|-gXwM6JMv`7 zR?LR0JfeFNNLzF=Mq+qvUK<{KlfpagNNv;e?=dgWNw)4iJ8_0iX(&B98WlWEjEU*l*W0OE*Yqq)2|Ig`jU3~zT4d80K^n5)5G-B zayM+zu~f4NKvAapfdPoMsT!-E8v|P7o6Ya-zC3?)VYXUKf@Xiewe{pZ<+p>xgSiY1 zGK`-!o@c18V$noLNdm={+J?yhz>gv+b7`Moc89~St=HH$;m3ZFW@A1$E>o&Z%7Lfr zE;`>p^Kv9)$SH1)2ayTe;709;FkK}2dGI)ByT0cSgb%+=h&bZ(^Pm_0Q7-2~i5@|j zc-V9DtH{XW#Osx*#SNV}JjpF0TE0!r7PFCs^6FufUD_K}!VDrl?g zqVEmaN7x`#!k89-(c!7#doL^OZ@*Dg4SnSMzZN|Npu3}}>|x5*o4_dm5Cpt??bton z_|s{p@HU}^DX;WE#e9b=`fUF&&8~4nrpwv+=oqbcBvyj5SLJ3@<+#;iA*G}q?l>q5 zx6<#9G#C!E=UWQ}!vC(naV>7IH_72JF7LsdXqwpRz2!H!fF%$4*ph*LnAQ?1CqP^5%v$!^V-2e9@*x;mVg}9_$>72vu0% z(Ejp_+6&9Z{$)nx-8kL>QE{IJ0?Z^hlv=TW z6T|>abZZ=etRXouGniXPzfSv4Yc10!2GJ0(d1&F$m(|0hpeqDC2vv$V$*2zij@Jbl z0^y&u`I86hl$jlY*fMm{`LUJ!?U z9-QguP+R@nC0UxtKmz3|SyE~kg7N7KkrSETScsP^vX>sfSB#Ke-{yZ-&g=|3PSvx2 z6(4?G3VizLycYm*6hL4-=J%i2Cu?b22)hGtL3$AEFaQUcJb=F)!|Eg$iuyYwAN z_H*kjY3pv?^kU z0OfKO=TNn(M4{mGxh0QfO9%sCw*H?dD^2~^@F^Ago@rjXb7v)O7QPR_c3qB$5sw zs}a4ffy4%N-7^b`gtcV6?){_dpP~L>-UXCZwED{(d-Q8IHa=AWf&#~8T3CTM^mak9 zBCR9D@_j@D$YM5%;Pc&%H7-3baJBQa82{ult*ZFiq$GRpD?ccDbWL0V$gZJ=+BP@O zjc{8hEIq`8_N%^3AF?&S6$PeF)*N+mC3T*)msmtC>a8Kwr4eWQoX>Q{8V$;C6xNQN z+iWK)u$8`psnSdc$}{Vu;asud1EW6tA7gR%6!i1-V5wEJ`>;k1IZJ7+=;9N#*h_!c zpC*jehjN-$l0+VcXV+r^)5l{b3etH0f|@n0 z0cwW6IzB@VI77Mtm{;V_^WWj)f2MuVoC#21@&E;f>F3IPVQl8%F2}FH_3Tv+vtWbD zYU`*m`UmDU6tZ157G@bSR$LKNO~kBPg;}~!XEI4WK!Oo-;IR}g2ka|CAlE!O&)u~8 z0!K#_UGoRDCg*=(fxGdkQNgrd!s8S0omQjcQxyxe+UkEw^Hjy%GaMvm;6}+2`fb35 zqSKq5L*Y|_wSjj$IjJd*V&ChMD&IUqk3ye@n}rmvf^s3>@v4U8o?)*t=c9kPCO?N# zR^_SHMjxb2iF5dKSO(?m4*z}z4HSo&a>w&0&LDoF6Q-C1#{j;0qb76ECkgz+uGTJi z3CG=U{rr0b4^UiDJ1mtew?Y&aW&x?5=G#gS4y(9CF=fngs(y6#-+cM#W#0O_l$?oNiJhK&m}X^(G_*i!Ep zj=iFERYII?cV!aA+@LN0EeL?%EZ0t`4kxi0?zk7!D71}#3=IY5DZR3w>x-Naz{_c$ zfO$XC;)1H5y3NVP@*`^z|3Wk2nJ0|4Xx~UT)~q>De2|GfW*FTg#j+|j*%FO?g|hq$ za63-OPVew9Im6&Oce~_FmbolepB1)_rY&pOO~gc(=o12VHolD5D6Q1MU};0Z=n<5KK8gs60@Z*H{JHMj@NevYZq=CWr{!kWcEfJ!>f5l| zsh60wi~6n7U1oo!^7vJa3F4*2N}6BQg!1r6cbm!f**s?%SIJIm4b1NTdJ{Es6(0rN z5ET^_<1M$bs?8Lvww0J~mfAC~uFFheWlZ5NvC4RPEHDFwjusbA);=Jng>N(@VN{Ca zE%%HWmub=sQVE-Zn-7=#c6rCMyOe;mZh#4~yJd|TAvvvB_7xC|yCQ$a>^jU{+q5ME zuCKk$c@nD<(LSk{ERZ{(OgLPrP%SO#bBhOSD06=2&_9r-i2nJiHg*2Z!Fq7&&%r>lyg?-&vxVEo}t%z!OSNLjeJr;z`xpJWKdL z(1o?_jJdYCpoZT+tjdOM=ydz<-)10K4xz?kL}ysNY5z~6ekG*X8G~JNH70HC3t|*7Z@1&O+E4H>ry)H1lCR!|ET(G zq_{E^pZ8v2T@#lm5yMhSu=`ko1bv(}koC}lalBnd;JU_~9p7Umf1 zSF8WkK~oDXC3$@5TI%=sDF<|}qPW)GjROKYy6H2#vri$kiN-jBQaBqLd6<@XsF{$$ zSXUX~v!~C$&*jWSk%UJ~E+)0Ew0`8@bMuIKno56;lbC~m-Idpc)Tm*U;ylrT;`M<6dHi~2F`xdfT8)S zqTj=m=~FM}3as_D3^qLb`iH@I#W7{@i>te-!8R9xbl%_8}Y@P(B`g2k%R6x24CF|4? z{%K*d*oaQJ%SWlohqtUL{=QeK8qWd3NG)U=1yafL1gg5@zx<%n5xM^DqA16S%AYKU zSe2z1e90UDOT3mrstcnLis)rxl2dXsc^1@W`ae*)i|uWo7bD-L66IQ5iZQQOf^_Ze zfAq`)W1v4e*8TBs$%C;A^U;w~XAfr)Y}MNB1MZfRsveCDl~#feI%a!3%w>XisZ?TYSO{67%+V%05e{Z0zjHLXqm z-F^$R_2VdHnE!$6RXcwL!khc3Qy}%1I&OGK4FT)q{0&Ejuv1=6e&Ch!)7eVkEO|TR z&SDqt(p6AFb)3~U0FYC_ixq!roTTDbIM{OTNP=_{dStK06;Pt+BMFB-yM2%4G#N=h z;5(TsXBL*K>R52;eBCh3v2XNcjdR!?52$cVHMNavs2&DlD)qxwJAjy*RkiNXnL#bc zM#Hlnxw#g$27=n$pPN>uWW^MxI#D-S7ah*5f6J9vKerU>4W`uW$S0#qb^b(c&2ql zb8T2B`g3Xk!${7>_5Cx z+rF`y)V)r43xorA5x`tvcm7hE*R?%e55NOl){vk9@waHystGX$6e|IfN0i0luSczg zAx=&;TK5FgrN6qon-5)Z=3d6?1#oU&BokB0BKKw{2q+G){;L_BCuk)~Isdfvr7q@N zldcsFENx@eA4wthZQDEpH;-DCTI0h$5^%{o8kbDquijQogu}aUj^q@Azz=fy_ZErO z6$C0BI$E?W#fy|?J**6q-cBa)<3D?ezL5KDa3u!S%O= zC4II#NJ*8#p+>^ z1Gs~mTgoC0ViCB#XGUsq&j0a&7o(MdTT20%?A~8luTl=_3t@|zbk6K|iYVox!(wd+ z*1|1w`{$N0>b3`!rL}wh_@-UPZ~@oe>z3ciJ^eq`hQi6;9raY~9HP-#MB1v2hZI?& z`r!#rYaK^Ms$UPHBxdsRKZwp30bquqVD<{6vlcDa%ERo2a`;XzXzx%DBKFO*e*V4v ztg6cByjH{{emqmZG3dAJgqQezl)hT@5lPG+`>Fc^f$si0&3DpMwd<}a7);Yq*PCXQ z>HP$`f1zuddg~j&4^IppC`7G^0$;1l=64$*#8&HmE-MSVVhm7wqVF zeNrhlCMpT=LL0bu-NCl?{da4MWq?I(xVA|^*(tDCg6O{29x0ozdy7Z7ZrdsS~_X1Ox)Z6Kaa(Xp4Y2&XD0WH_3w1el2WMS56+^Qir{yJdBxgz3FYN z{ML{vS5~>Z(>`L}b5Q9~G|OEC$6-V()Nz4UawobGziR>qiUZJz64frW_FY9u$@^T+ zV354Zk?OEq!90raRHm}dE}P2yN__{(8F>oN>(5cpiKA#I9Y#i@_%o(YERiCY*$6I@@S@W{ zLvxW=cKw0*@fd|Ep_5fv}FFyKs373UR zWpZ!<#}ku!kO9W5-Mc21;XbH?87e>sqQ0l%{Le1gI~Ig&4-2fzD)nYh4&b0yt-Y6j zz(Z@D!(Ann`|ka63$L#syj+|pn7-h9-@O$FSkDg5>X6sU_+dQRsOyv338fmmUf4GN zp<5sNOTO|D%qa-yJC9^tfb8Z zz&_B33PNS+h{Qja&-rD52>Sp;M6N;^zg*pA*=kZ@-T=>tC_22pe^+O?{kH~KaxtPk z1HU%b7|>f9WA-;F++hkj1E_?w1}mYgMrT8UBnf+{2nUx>{Sg@#>iI|oa|wMg5>1HN zaHkIojlOSllm+%zA~=||pXfVz;(l|Di~f4T;-P`J$Puo>R2zK zIA~zqhscczIR}2HE0{}4DOA>ko0^$6fS2<9FOBy~QPc zque(UH*y5Uh0urdbXt{R@!$Q2F_!;AD1kvJQMu z#BL4B!l<15^%lA=_igRg(Xu7Gr@Brw`bdSwk>Sy>UMfl#V z$(vw(NWZ%f=F&Uscbu4?>AMT%>6x==@B8!{!}(R1&!+>kP5kFg-bfw_jOfGF?BgU? zQ~(X@Rr09EW#@Z>P{qyoRk{7IIrbxAqj?f4)SIrgK+xb0v+B(=(VVkjPY9s7J6YiQ z`1p?OY!A2tL6MdxyOdnu`7nLHj?~JTq`2I-v>i<;`I*k;f{wO+< zx+p2x@q{vLwW*&QVucu?j_vqRam;SV>@IgYUS(YYK;{zHxJ*B%9RpS>AH<<^hE?f~ zZS#+c(B4k5pgwnt@vY zAR@tc-H|;cSCfKl`*$^55hSu&=+0RSoXJUA=}yzRQCT_J(n@+GeUL;*8PsB|s#G8O zF5M+eMEf1ewo+Fo+{F204s#b)L8-{W(NcrigI0}|R z5e8Y z4x_u%{=*>si_W*%MMNn;t*+&XGaYbCZv^sMaekrg!xq*{O~9H|K_wD-`cdV+I-0pf zpfxZ(J(--c2x>9>`tB~sI)%6wxRF-sgMzN1L9^z$pEvWU%hy0U?_0&`}K)U42S}Cmt%-N{F-QdNaxaw>|F_ ziH9ypgYS?#4RR`|%qRY+kC_l=0%B5>DW3qF(U=|XWRtkT_37+49C1_RbFwKRuipp_ z@ny*C!z>Vva17rd5#NRE@I`d@5UR=0wjju>Rj>n@Mt=Bl6ezkIWUG1$K+2q*bXag< zeDx;YQh34o6tjfMdkCQINssh+DCG(B{{8epW3$n@8kCxeLd?m&Du)Hk*vE0$an%CG)a)8|j`PIwFC8q1mZ+D)(EZ+0pw&;I=Z&kL~k1Wk=h+FpY zji~ka_)laEeI&?PDMazx*cY0-CVnZem@fYlvnqt}Lq zc$m@7evM@vqTK{=OSa`COO+I+z zH8O2TK%7e#J)u~o)*la?Mjr)sWb-fJ@cPIQc+QTROd#NqFj=1r`K17uJdCeWQzz{M zxUfTa0?O+st#je~L0dvISf@!i%+wz7EGu zs_KfLU}mK@xOP5-=WzfU^XP!{u{-!hDdqlXVIq~m1`kc z*eOg7_l7Sku?98|oWrehPX76UxX$~P7Ix(|f(tE_mci)mM2GPb*Q>wE5^YAqSPoyeMWTJ4Xy$RW8DJackEskKPVpbr3eduei|cF!j6l?n&F zUohLcU?t+dPjlfBtRQZ~+q}hqfk7J|))j(MHbkLnd`Nfg_$7_R7P+-})I|aiZ04=Sr?zTG+a*?kB#>L{f=%Y}^o^Eh5UP98g1B7TDzCQ&q|q^Ia&j>ZAgn9^h|obdja-Lad(mNjSZ2b?6C^A~AGR34 zqU6OVvHSthWNJ=XdADvi73NL}FsYTqL%*DR!{VyxeT$HqR9H-i1dK7|EPAtNEg>8) zYucsluB5}BgV@oke%nIR#~khuE~%F>(pW?30a^KRoQUa&v+o{V6Bek`E=?0>2N*vv z7g%=vR-2IBJ1SIg9VZKDdR~E%f z&1GkQi%)1qzF}QgmGserTG@w(@wikvrF;A%fJpOBk)5$SLDI&#(xT!5bAHzNDyMy7 zgWzNr3S8&HsR#~fW>KC#ytcqw;K-`dn^S!gQZOZj#)a)>S|C^{&|%_CZ-~xMXmBat zEdg2>HxGYYb~?(($#OUA+BMD2v_AN7Uar#D>hdj7s^16r?VAzdp--v6!|*1tCYlp* zFBp_XQ;{w*yO!yzHH+V>&HOab>|HI+;AgdU#l}0-R-Vrx*lbd2m8!`A4oBQ3j8Ol~ z%P1MEOmQRpYJaYmT6JIt(cKOEh7u_5BxY4q&r}d#lXHL+!yTefD)aTn#?`>SBfTrM zH|!+x&F11UfPKUQ;WL3Mr6q5g{fi<<93!U^T&_pASuVL{{wgqM&Zv{2b<|yWf&)xE z9SN-%bh*Wb5%R>HCyW;Ef#S*ub1zTpL+KwXD}z8($K?sxY~mf7{eG+}m-9R{s4?%( z52BsV_8PxaV2&~@o?|boe|vcrxu(gUx7_X3r+_*PXkYXNZtJS z%ThHhQHcg=%+0;hBEqG=otgmy)L(G_d!QKs0kJj}#ye;-!_zN}s@`0AUpT3$?Fbzu z=1%67T_pOjv^H5#wZJMl#@#bcVI62rc1?t7FFPx*q{;ltlp8I{hIul+5VaZ5iTZA* z*878c|0P`7OHLMR&#<--MPal~yT^tK4)4dOq?PRHTFHbqSNYjg`l5PLbnRiToFre9%wG7vUDBTz+_PrNDtfqJI5NbM9TF+n%C8 z^IWMkMJX~jScUV*xY6dyQ})G$tJGlzJtSR?H?)l?cC@aLMwT}(RY$Vf0wW_F3 z3a3?obZx{@dDz&*sScl{%AlY#W1D3|vnSg%_BUYf86Y~gIB(%T>U>B(sFF_UIucW6 zP;R6^uHV_S?HOxNL-@<5snUTi0+bLqo6Ns^St1+($!>1#mMvZYC@0uL)vBKXBL08q zXrubKKr`fk>(USjQ&=<;93;~uHzpLSmS#8$m3y+Z!_+>QYp$^+9YJm%=kYSFk1Xkb z+maGS2Tj4aTsJe?v7x>rEH&c|;Hak0^r0!0^GE-mqBHSJGVl5@n0K>a(jy!uFKxm$L)IIXFP&{gDPLJsVpfKFtJI~3W$Sw+ijS6nCDxSxz zetY3#IYLOkiblP&IdMEDWY%FEutE9O^XSwI#+X4qElNkcJ&YNgB)Zk=)h62q8-|); zl4&Phv(}|?ycZihg=RgEJp1ted~J}hEAZ`?S-flS<^YT&@w%$Oq0jB-E#`1icWfEm zm2E_lBSBK0H^o(dq6!28h15CtBA)-*hC8r4rA%52OKE1*a5WI&3Jt9nld$sAr*!HK zGVHB_h10vMJl@?qA^>#}ejY~ODc)3o5=MY=(n;a^CGsEHa!8>J$4iwruC48Zsf z^CrkJ6SSyZbt;1XX_opJaF!k6X`zX==O zTcnt8|Ip0{-b&WS#O(X~LR`5sJ2fkg?jF9q2>tU}v|(|T5VTtAU4B^w;gRWI$YN5v zF6%Vgmo5X;mLt*>S1T3x?jD>;sIY&ORrU8S!t1g$i;dk(Z|VwBWvIm=<#G|A-^zbF zv(WXMkmZ39Z1=2~1+ml63(U=d%T;m3k6mgM68piwK5<>NIB19Qq|C$NipqJ*u(Z(ef32@*KKYbc4q*2sA(h&3UZ`gUqB; zb~{w2$-|Fm_s!6EKW%mTmg(D+X>3`Y04~lo1Zu_+jLd)n@KtMTX4v=P|1&4?GKVRVL-{j&L_B<5sf0L)p=paM#?ImwdKOd$+b-H3HsNqjZT9BQ-)zwUa`dC0OrKs@6#p;sT zECD0Hbe!ey&+eGmU@|+%7-QPRVt+wIu8rh^R!%eM^JJ8bZ$7_3KwFv*-?VS$5&eEi zPjIDn)x%ODD+>DZNnSU1c|-Z9^=9&XP~&r>bghwBwIBVZhQHyX%~w5k#$;nLRv+T*3uN}iNv=gxJ8s%$EztT$rQu;opKBC#M@*%;ZwP>XIu5BY z;tnJ>P-^N{yqN54n51OXHwp7yO6kEH%}3pXZrc)8snpQIDB%={02VE>0UHX6h`ADA zM8~u}*{S6LMo0xN)2&A1zMicvk$k84n&J$wQZ#Fd9SlqBrQPA*+1-9oD@j|N)2sY{ zYlXG3AZPLNX_9HE*#h(fy;+yD?7fY}z$Fq5t(#c@iW=#QzEwdYW==PwoRGEgZ0~E- zt`SGa?tj0`?)M|SVN|~t+tj3(ZK;05%c}evV4LRD{iKd#M^A!y7P_Q0T9`D;wR`0) zwaAP=I5`;nb}>AvFF6u}7YLO3)`au=A}wBPiM3?8U0Nh7>8D@G!M85l&w>B-P#w`k z&%P={a!=MB0hT={w=_KN*6m4Ot}@lSM1Jz0u7$3z0s5VLn>`(Sf%aUmWsp0$nn8ZV zI5*x+p$;|r%g?`hax1yVsh`q|{4SQw2C5^cL6qH)T#GpXmN9*lQPB?8=PZx&Z#`=c zs}aQkJKWu>o;s`b;3r=FEg(DP3XmRlMzyH&jW2!#IttIYghodYF0*~$*JjI*4kCyz zW(VQ^UHZ(jD5@2ZE6aGGL?;v@?sjZUv**;r(32fjai|;QXmBWui@{!c4UAgbQ^W9$ z+w+0GGo|s>u#1OFag{KA6kv0l9h#NZTFD#8ZZB&t);#yxtPp+s8Ti%sRC_Myd8kY7 z0mH7gs89GzF!{^f0N;(`Ul`~6BIoBOCe=@Tj^yW`&?2U=is8xAZLx71bI1(#uYU~` zoFCcO)EbUipbx;qKI*O^wNKUjvC@NB>ECxPahT)92V?;(Ov38-w0MpAh?pY=2WKo# zik|HcweNNf$jV;WH5Bc%G!J0#t&or^SyAtdbbFxRPjw8k zHKz$JnRX?lQ?m3|zdKN?KmV{W<_dzc``5$hc#`jJOeS5m*Rao~)@P!M+;Nh3-lJbXbFsz3RXh5Q@%NKGb6}a19ANZ@F9riI zq~s(Q#AAH0#O-81S&dt0JKDEHGcOBA3`*_MbRC#`3(o$V^ocefMVj-tCwA zcc8iJJH1$NC;A`*&?abmm~^LL$)R&E&w^gbt80Z6Y_rt|7U&Xdt1PH|D+S^g&8G5O z2x;@7nHFkVVM;MOXL^ywXhKdy<#@Nh;a`{3Mow&)4DN(cPHVl_PRecN1*IOu=;)Za z9a>a3M{~@QA^c(G_{rpq!2Is05jG0M<~*xC)v#6Iyikr9m+=Sa+aGFwso&dK3#)Am zH1Sem{W>>TMlKD8&av2M!pF~=;gCVAGkkxE4Rc1Z3E!C!6QPYE^_E8U-99d)y7pkl zK(t<@imLM}+X&v9UU~EdnULY%qJmbIjWi}{s0W?U#k};6SDrsG(wdoUfyMZ%fT{9} z=VQsjtM4mobIUYw7uOO4TrZq(^IlTfsXKwY1fDknDRed)Ki0F`+UMQ-&@_t&uUpiP z;J;c!B7q|BV$_%uxt{I}j{Kp0dXZIOrIWp3`~=>AVjAVM0Rt1cL`;od3wgV9ZwGm7 zN0Zokco3AOo;Yt;&xV_k#qjq)6~4BY0jfonCITrU*H^^dEnAhnrjwp~*F%!&F@yVz z;K4De8WiBc*u0HOI|{&Pozci&aZ59tLt^7o>#q~IboL^HWf=#2yEo?P?4qXEu9x)z zuTMr0vQe2=5awS}mxABZb~JydPsZ{sx6AsOmTBb?kpnitQ+jD$Ld_>F$Y}LwjEud@ z811wM2ZRR<{4bIc2udpNFqX3g_IEM{*FER-dX0I+tbkyU=(KR~y?W>RI1u&~Ehc93 zD76JQr85H9#$-ya7j}ALPj`A@UIK%?wN6M{*Qb40&#%r0=P!8n^e&+`7UsWUWZQ|G zVN30cAFEV=2z=`O7v21TH{k0v)LdEhXKCV5%3!nQFk{2K;3B(NnAgd8R7VHp4^bm1 z9gDAtI`@KGIa87C6 zB-`rd-3~NcTnOdVApw#W{4U^g%tQ>khq&t&m>vVH#ZXI-zS@bml}v*#C2OKKB^ujI z&8b6Hs8-j$N=Z4NKO)Pzvd-Iaer0&aMD>o7bi7;B&GK_Zu3YEz^)(s^963`us~Pkz z@=DIkLv7WLLQW4>A>ep_XrW2%5sX(a@<)L#MK2I5mdL2jE; zhDz&gcS0NWPu$51t&xu4z5K3}9Bib@D*tHvEMW!XyQU;*`yCsW_n21q-$n%717~%w z8DZqEDkQU3eF;lU{?_z;Si}q@+vald@xrb3rN3Oa7%(D_L-hqpdJ-_GToY6@5}eNN zJCkwQN322&z(Z1w-axg8DhfhFdePj`C|msue}ZX){ah#~x;*frEW_Q&AAExVEE*U_ zaDzLdJmrAdN?t897to?(%io4;mg9CS|KahX7{M|B^=CqZ(fKQtu199)SL$FHI&C(wVJOaG56t%XTh6`V zXAHW%vP!}Iql58M2E#i>GXXB8AGIz?A+M9#SKcM6IG`kb8rR&?TgjIUlaVc;?Qm!- zVCJp)Pcc_Tp5^2%)n)i!LT1r((5t5}G=T5T?%hz-?P~L`POaAwCrH!MQleFk){)g^ zvDj}-Y;Xt4rjwpY=YrYsLsCiy&^83FMN5Xmf}f5vIjAdKZft-StyzA1Z# zIu}krE!7e`CQkmr;G70X3W6fwzJ33d_P*TaKSW#aW z6(5_DWNJ>2H$pv$xYhXJJX)%3Qc;Xl)JnUvudT2q&pLGA|I3V#ZZBm3GK}iPbv^&a zG@aPP@9mko(CA6jdN_8&gvWo@1cJ)x(UVRjXkn0gvKo_jHxcx)`<Y?z5i6qnJ_wAjG``^d(X`1HNVptRgbFOaz7i`i<#|H#TFe?&<&~wwyi%h z^+k%$k^_dfWF;8WC-Mk|oHf-{r^r@UrnSEO-HN@i;xAR!6r^b15czFykdcmXy=o*Q z!`K>HL&H0&0#-+-ClgH?B;Mh z{yk2S)aFB#)}6M+Sb4-c*V&~G!rs;P_IO5>M%orBhQksvCbhGo>!lm}cu1zrwl4J( z@|?2=BjRZY{lnlx(LKVOq3Q{?g$X63SOUH?lE=76Vv_Rb*z?XRVD{@TNqksa82hJ& zyjiiaF&CNi$vtjF%G^S|?zy2pZVOX?Y%V6+q4&PX67MPqx1tPN!o&Zwd$TP9AVnee z_ISC_r*3UOMd7sQI(Y8ECdq1k*l!VY+%^j4S_ol3?(f*)d#jCwZ47OzplOAj@0oKZOVHL=C=KWKml4si& zza%APvc^(wUa{;joeDe{U&x_xC&gQ=;jaAtRZSfm%=M}p+n%NPE4&7n@O@wFbF}zE zcF|B?Z?DSA{hm%6T$+lpxkvoBf#^Kjg3W$T>OOIN=w1qYvKWrDSKjSVAEZI-?{D6U zHUk^V*Y-LOZvc+lj-VyqBScyu_38n)b5rmcU~TI_79zdia0*Pp3jvH*kihe!3Gp7m zZXtDZ{mw4h-R4tmb?qPPzEdUpN-dn=wZ61fyOb~f1}tUWzMh{{QLgOejnE5}?q@SG z$YUFfMdFgdrFDy+heyP$3h9|N@5Rt3DA66010=np>No+y+N@D++0|*)iK0)+bQDLr z*^mDY>pw6e>k$^ax1Yf(Dqn=T*D)?Wq(!x_y9*(Q`7V?MMZDnUR@VM+isJWk$zHEs zEbKtW9Q(#=^#egW0zrgJqqUSqokd(6YbCu%$=kwbUpu_&>`-Gzm*IO=uTxh_w(N8@ zD~`EsZ?|#@@XaK(Vok7WiL&dAATObsNCKrXbAbmbK}e-shgg=rw$RbUWfWcy{Ev`R zU1}|O<7Gxf%*O!VD9uPmP-1^8=Dp#iC@`hG!58L{2)7(q$c-5-m$wiR%(x5?SQVup#cw5pvN(vUHbgC({-6WLsE(`MN3`Vnu1wdukRew9(2dnUI+dZ!4-{V+G~Y2 zEOG2S0WsmQUSYHuoLSa3dg`ZcOlq_Q2n`LE#Hjpe-jBR+Hh+)04*vVHz>Rn`Y^b6I z7mp7H^5Jr`zL=PRbuke_)@&z!g_^^r28oQI>9qq?>r zEkbfnc`Au1EnY6%zsiEnc1+fcx#wzEI#&33ov^W)9mV9B0UmAJ1JZ_(!o4k#Slx6U z>lcj>=W+O02V7w(_ms5}p$9h_r=^w8fpmvw*5BPHGP?*HHZj@hJzsF#nD*D@<{&y+ z`e^x^JezFCWtha3zmrpY2H>Y+IW)5N;lKDgH_KK$_Tib$_O_QQRH<;O@H2;hL%xe` zI&h+@WNwi{`3aAz%k19yQeFK^ane{-MJ?$|-E2(($yb(*uOSVhHldsLz-mk5=Sny- zc1w*h6DEbH6yENyH;GZ^6Vt$$8_0Th6$(=--t#~owk?5}LB-!ySL7eC^$By&t%X$+ z8c3EM0j{rjnoGL?IfY7gqvG-FoXImh||Rk zCTzwZarnbTgBOAX7|s;$N6KMyDOPN45ZB?3ghviOR5NuLRFxb7Ilk_CznR}-ek2GP zJ^f`iXTw5tBr%fqpW^gIs)+c(d4tqJG*~xZ=%-aDpwt0QV~6x;HvU@1U>W4J@)_Chi#`2GLvJM@NzZ$qlDx1Gx?AZPy6 z#bw)aDbqJ|xg!Y{dVQ|g|NS%RQiKj5%Cs?(#JE}O+U*z!Tk(l@W)*mcfa0Cp9nLhgPe7@ggDFJBV1HLOl>_MQS zitGR_k-7-d4_1I|VmF!HGFL>N(OHNzZVY*(Xbp(ILP`=lu5My`a1y0Es z@GdIE2+#9(5(9AH(F<(iH8EI|>em#g`0Nt%@iHHTp{{NV;0o zs%ARZ!V_3_9ogM zBTNZ^&L8#x6ckS0yV|^w=2b5*$JD=0V_N6FmHt%`ZRTrgvF5P@fT5qlcCv_QCBc1I zTBAA@uL<7$vgBO+jmH@I`S2`RM(Ps8WQvuB4fm?FhH{&=}OIZO!9!IcI&*;zk& zq>FkQJR82sq+Z-H9D2*Ku6BJ}3jN*NqP+5oFM#1E9K

!GU$$Da{#fwZP`Nqw%E} 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�E^&ll^jo0eKZ(A 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