Skip to content

Commit

Permalink
Issue #114: Scanning by nested properties
Browse files Browse the repository at this point in the history
  • Loading branch information
derjust committed Jan 23, 2018
1 parent 917c660 commit f77b4f1
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 9 deletions.
1 change: 1 addition & 0 deletions pom.xml
Expand Up @@ -399,6 +399,7 @@
<table>src/test/resources/customerhistory_table.json</table>
<table>src/test/resources/installation_table.json</table>
<table>src/test/resources/auditable_user_table.json</table>
<table>src/test/resources/person_table.json</table>
</tables>
<port>${dynamodblocal.port}</port>
<dist>${project.build.directory}/dynamodb-dist</dist>
Expand Down
2 changes: 1 addition & 1 deletion src/changes/changes.xml
Expand Up @@ -20,7 +20,7 @@
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/xsd/changes-1.0.0.xsd">
<properties>
<title>spring-data-dynamodb Changes</title>
<author email="zeeman@zeeman.de" >derjust</author>
<author email="zeeman@zeeman.de">derjust</author>
</properties>
<body>
<release version="5.0.2" date="" description="Maintenance release">
Expand Down
Expand Up @@ -71,14 +71,21 @@ protected DynamoDBQueryCriteria<T, ID> addCriteria(DynamoDBQueryCriteria<T, ID>
throw new UnsupportedOperationException("Case insensitivity not supported");

Class<?> leafNodePropertyType = part.getProperty().getLeafProperty().getType();

PropertyPath leafNodePropertyPath = part.getProperty().getLeafProperty();
String leafNodePropertyName = leafNodePropertyPath.toDotPath();

part.getProperty().forEach(System.out::println);

//PropertyPath leafNodePropertyPath = part.getProperty().getLeafProperty();
//String leafNodePropertyName = leafNodePropertyPath.toDotPath();
String leafNodePropertyName = part.getProperty().toDotPath();
//TODO #114 - is this correct?
//TODO max deepth of 32 supported by AWS
/*
if (leafNodePropertyName.indexOf(".") != -1)
{
int index = leafNodePropertyName.lastIndexOf(".");
leafNodePropertyName = leafNodePropertyName.substring(index);
}
}*/

switch (part.getType()) {

Expand Down
Expand Up @@ -50,7 +50,7 @@ public class DynamoDBEntityMetadataSupport<T, ID> implements DynamoDBHashKeyExtr
private List<String> globalIndexRangeKeyPropertyNames;

private String dynamoDBTableName;
private Map<String, String[]> globalSecondaryIndexNames = new HashMap<String, String[]>();
private Map<String, String[]> globalSecondaryIndexNames = new HashMap<>();

@Override
public String getDynamoDBTableName() {
Expand All @@ -70,9 +70,9 @@ public DynamoDBEntityMetadataSupport(final Class<T> domainType) {
DynamoDBTable table = this.domainType.getAnnotation(DynamoDBTable.class);
Assert.notNull(table, "Domain type must by annotated with DynamoDBTable!");
this.dynamoDBTableName = table.tableName();
this.globalSecondaryIndexNames = new HashMap<String, String[]>();
this.globalIndexHashKeyPropertyNames = new ArrayList<String>();
this.globalIndexRangeKeyPropertyNames = new ArrayList<String>();
this.globalSecondaryIndexNames = new HashMap<>();
this.globalIndexHashKeyPropertyNames = new ArrayList<>();
this.globalIndexRangeKeyPropertyNames = new ArrayList<>();
ReflectionUtils.doWithMethods(domainType, new MethodCallback() {
@Override
public void doWith(Method method) {
Expand Down
@@ -0,0 +1,37 @@
/**
* Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.socialsignin.spring.data.dynamodb.repository.query.nested;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;

@DynamoDBDocument
public class Address {
private String city;
private String country;

public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
@@ -0,0 +1,59 @@
package org.socialsignin.spring.data.dynamodb.repository.query.nested;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.socialsignin.spring.data.dynamodb.repository.config.EnableDynamoDBRepositories;
import org.socialsignin.spring.data.dynamodb.utils.DynamoDBLocalResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

import static org.junit.Assert.assertEquals;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DynamoDBLocalResource.class, NestedPropertiesTest.TestAppConfig.class})
public class NestedPropertiesTest {

@Configuration
@EnableDynamoDBRepositories(basePackages = "org.socialsignin.spring.data.dynamodb.query.nested")
public static class TestAppConfig {
}

@Autowired
private PersonRepository personRepository;

@Test
public void testNestedProperty() {

Address usaAddress = new Address();
usaAddress.setCity("New York");
usaAddress.setCountry("USA");

Address deAddress = new Address();
deAddress.setCity("Frankfurt");
deAddress.setCity("Germany");

Person p1 = new Person();
p1.setName("personName");
p1.setPhone("phone");
p1.setArea("area");
p1.setAddress(usaAddress);

Person p2 = new Person();
p2.setName("otherName");
p2.setPhone("42");
p2.setArea("otherArea");
p2.setAddress(deAddress);

/// personRepository.save(p1);

List<Person> actual = personRepository.findByAddressCountry("USA");
assertEquals(1, actual.size());

actual = personRepository.findByPhone("42");
assertEquals(1, actual.size());
}
}
@@ -0,0 +1,65 @@
/**
* Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.socialsignin.spring.data.dynamodb.repository.query.nested;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import org.springframework.data.annotation.Id;

@DynamoDBTable(tableName = "Person")
public class Person {

@Id
private PersonId personId;

private String phone;
private Address address;

@DynamoDBHashKey
public String getName() {
return personId != null ? personId.getName() : null;
}

@DynamoDBRangeKey
public String getArea() {
return personId != null ? personId.getArea() : null;
}
public Address getAddress() {
return address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public void setName(String name) {
if (personId == null) {
personId = new PersonId();
}
this.personId.setName(name);
}
public void setArea(String area) {
if (personId == null) {
personId = new PersonId();
}
this.personId.setArea(area);
}
public void setAddress(Address address) {
this.address = address;
}
}
@@ -0,0 +1,53 @@
/**
* Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.socialsignin.spring.data.dynamodb.repository.query.nested;

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey;

import java.io.Serializable;

public class PersonId implements Serializable {

private static final long serialVersionUID = 1L;

private String name;
private String area;

@DynamoDBRangeKey
public String getArea() {
return area;
}

@DynamoDBHashKey
public String getName() {
return name;
}

public PersonId() {}

public PersonId(String name, String area) {
this.name = name;
this.area = area;
}
public void setName(String name) {
this.name = name;
}
public void setArea(String area) {
this.area = area;
}
}

@@ -0,0 +1,36 @@
/**
* Copyright © 2013 spring-data-dynamodb (https://github.com/derjust/spring-data-dynamodb)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.socialsignin.spring.data.dynamodb.repository.query.nested;

import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface PersonRepository extends PagingAndSortingRepository<Person, PersonId> {

Person findByNameAndArea(@Param("name") String name, @Param("area") String area);

@EnableScan
List<Person> findByArea(@Param("area") String area);

@EnableScan
List<Person> findByPhone(@Param("phone") String phone);

@EnableScan
List<Person> findByAddressCountry(@Param("country") String country);
}
27 changes: 27 additions & 0 deletions src/test/resources/person_table.json
@@ -0,0 +1,27 @@
{
"AttributeDefinitions": [
{
"AttributeName": "Name",
"AttributeType": "S"
},
{
"AttributeName": "Area",
"AttributeType": "S"
}
],
"KeySchema": [
{
"AttributeName": "Name",
"KeyType": "HASH"
},
{
"AttributeName": "Area",
"KeyType": "RANGE"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": "10",
"WriteCapacityUnits": "10"
},
"TableName": "person"
}

0 comments on commit f77b4f1

Please sign in to comment.