Skip to content

Restore projection of class. #1319

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,12 @@ public N1qlSpelValues createN1qlSpelValues(String bucketName, String collection,
String b = collection != null ? collection : bucketName;
Assert.isTrue(!(distinctFields != null && fields != null),
"only one of project(fields) and distinct(distinctFields) can be specified");
String entity = "META(" + i(b) + ").id AS " + SELECT_ID + ", META(" + i(b) + ").cas AS " + SELECT_CAS;
String entity = "META(" + i(b) + ").id AS " + SELECT_ID + ", META(" + i(b) + ").cas AS " + SELECT_CAS + ", "
+ i(typeField);
String count = "COUNT(*) AS " + CountFragment.COUNT_ALIAS;
String selectEntity;
if (distinctFields != null) {
String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, fields, distinctFields);
String distinctFieldsStr = getProjectedOrDistinctFields(b, domainClass, typeField, fields, distinctFields);
if (isCount) {
selectEntity = "SELECT COUNT( DISTINCT {" + distinctFieldsStr + "} ) " + CountFragment.COUNT_ALIAS + " FROM "
+ i(b);
Expand All @@ -176,7 +177,7 @@ public N1qlSpelValues createN1qlSpelValues(String bucketName, String collection,
} else if (isCount) {
selectEntity = "SELECT " + count + " FROM " + i(b);
} else {
String projectedFields = getProjectedOrDistinctFields(b, domainClass, fields, distinctFields);
String projectedFields = getProjectedOrDistinctFields(b, domainClass, typeField, fields, distinctFields);
selectEntity = "SELECT " + entity + (!projectedFields.isEmpty() ? ", " : " ") + projectedFields + " FROM " + i(b);
}
String typeSelection = "`" + typeField + "` = \"" + typeValue + "\"";
Expand All @@ -187,22 +188,22 @@ public N1qlSpelValues createN1qlSpelValues(String bucketName, String collection,
return new N1qlSpelValues(selectEntity, entity, i(b).toString(), typeSelection, delete, returning);
}

private String getProjectedOrDistinctFields(String b, Class resultClass, String[] fields, String[] distinctFields) {
private String getProjectedOrDistinctFields(String b, Class resultClass, String typeField, String[] fields, String[] distinctFields) {
if (distinctFields != null && distinctFields.length != 0) {
return i(distinctFields).toString();
}
String projectedFields = i(b) + ".*";
if (resultClass != null) {
PersistentEntity persistentEntity = couchbaseConverter.getMappingContext().getPersistentEntity(resultClass);
StringBuilder sb = new StringBuilder();
getProjectedFieldsInternal(b, null, sb, persistentEntity, fields, distinctFields != null);
getProjectedFieldsInternal(b, null, sb, persistentEntity, typeField, fields, distinctFields != null);
projectedFields = sb.toString();
}
return projectedFields;
}

private void getProjectedFieldsInternal(String bucketName, CouchbasePersistentProperty parent, StringBuilder sb,
PersistentEntity persistentEntity, String[] fields, boolean forDistinct) {
PersistentEntity persistentEntity, String typeField, String[] fields, boolean forDistinct) {

if (persistentEntity != null) {
Set<String> fieldList = fields != null ? new HashSet<>(Arrays.asList(fields)) : null;
Expand All @@ -216,6 +217,8 @@ private void getProjectedFieldsInternal(String bucketName, CouchbasePersistentPr
if (prop == persistentEntity.getVersionProperty() && parent == null) {
return;
}
if( prop.getFieldName().equals(typeField)) // typeField already projected
return;
// for distinct when no distinctFields were provided, do not include the expiration field.
if (forDistinct && prop.findAnnotation(Expiration.class) != null && parent == null) {
return;
Expand Down Expand Up @@ -253,8 +256,10 @@ private void getProjectedFieldsInternal(String bucketName, CouchbasePersistentPr
}
} else {
for (String field : fields) {
if (sb.length() > 0) {
sb.append(", ");
if (!field.equals(typeField)) { // typeField is already projected
if (sb.length() > 0) {
sb.append(", ");
}
}
sb.append(x(field));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2012-2020 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.springframework.data.couchbase.domain;

import java.util.Objects;

import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.annotation.Transient;
import org.springframework.data.annotation.Version;
import org.springframework.data.couchbase.core.mapping.Document;

/**
* User entity for tests
*
* @author Michael Reiche
*/

public abstract class AbstractUser extends ComparableEntity {

@Version protected long version;
@Id protected String id;
protected String firstname;
protected String lastname;
@Transient protected String transientInfo;
@CreatedBy protected String createdBy;
@CreatedDate protected long createdDate;
@LastModifiedBy protected String lastModifiedBy;
@LastModifiedDate protected long lastModifiedDate;

public String getId() {
return id;
}

public String getFirstname() {
return firstname;
}

public String getLastname() {
return lastname;
}

public long getCreatedDate() {
return createdDate;
}

public void setCreatedDate(long createdDate) {
this.createdDate = createdDate;
}

public String getCreatedBy() {
return createdBy;
}

public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public long getLastModifiedDate() {
return lastModifiedDate;
}

public String getLastModifiedBy() {
return lastModifiedBy;
}

public long getVersion() {
return version;
}

public void setVersion(long version) {
this.version = version;
}

@Override
public int hashCode() {
return Objects.hash(getId(), firstname, lastname);
}

public String getTransientInfo() {
return transientInfo;
}

public void setTransientInfo(String something) {
transientInfo = something;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2012-2021 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.springframework.data.couchbase.domain;

import java.util.List;
import java.util.stream.Stream;

import com.couchbase.client.java.query.QueryScanConsistency;
import org.springframework.data.couchbase.repository.CouchbaseRepository;
import org.springframework.data.couchbase.repository.Query;
import org.springframework.data.couchbase.repository.ScanConsistency;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.couchbase.client.java.json.JsonArray;

/**
* AbstractUser Repository for tests
*
* @author Michael Reiche
*/
@Repository
@ScanConsistency(query=QueryScanConsistency.REQUEST_PLUS)
public interface AbstractUserRepository extends CouchbaseRepository<AbstractUser, String> {

@Query("#{#n1ql.selectEntity} where (meta().id = $1)")
AbstractUser myFindById(String id);

List<User> findByFirstname(String firstname);

Stream<User> findByLastname(String lastname);

List<User> findByFirstnameIn(String... firstnames);

List<User> findByFirstnameIn(JsonArray firstnames);

List<User> findByFirstnameAndLastname(String firstname, String lastname);

@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and firstname = $1 and lastname = $2")
List<User> getByFirstnameAndLastname(String firstname, String lastname);

@Query("#{#n1ql.selectEntity} where #{#n1ql.filter} and (firstname = $first or lastname = $last)")
List<User> getByFirstnameOrLastname(@Param("first") String firstname, @Param("last") String lastname);

List<User> findByIdIsNotNullAndFirstnameEquals(String firstname);

List<User> findByVersionEqualsAndFirstnameEquals(Long version, String firstname);

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
@Document
@TypeAlias("airport")
public class Airport extends ComparableEntity {
@Id String id;
@Id String key;

String iata;

Expand All @@ -49,14 +49,14 @@ public class Airport extends ComparableEntity {
long size;

@PersistenceConstructor
public Airport(String id, String iata, String icao) {
this.id = id;
public Airport(String key, String iata, String icao) {
this.key = key;
this.iata = iata;
this.icao = icao;
}

public String getId() {
return id;
return key;
}

public String getIata() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ Long countFancyExpression(@Param("projectIds") List<String> projectIds, @Param("
+ " #{#planIds != null ? 'AND blahblah IN $2' : ''} " + " #{#active != null ? 'AND false = $3' : ''} ")
Long countOne();

@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS)
Airport findByKey(String id);

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
// @Meta
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2022 the original author or authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.springframework.data.couchbase.domain;

import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.couchbase.core.mapping.Document;

/**
* OtherUser entity for tests. Both User and OtherUser extend AbstractUser
*
* @author Michael Reiche
*/

@Document
public class OtherUser extends AbstractUser {

@PersistenceConstructor
public OtherUser(final String id, final String firstname, final String lastname) {
this.id = id;
this.firstname = firstname;
this.lastname = lastname;
}

}
Loading