132 changed files with 1546 additions and 2063 deletions
@ -0,0 +1,60 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.common.data.page; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnore; |
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class PageLink { |
|||
|
|||
private final String textSearch; |
|||
private final int pageSize; |
|||
private final int page; |
|||
private final SortOrder sortOrder; |
|||
|
|||
public PageLink(PageLink pageLink) { |
|||
this.pageSize = pageLink.getPageSize(); |
|||
this.page = pageLink.getPage(); |
|||
this.textSearch = pageLink.getTextSearch(); |
|||
this.sortOrder = pageLink.getSortOrder(); |
|||
} |
|||
|
|||
public PageLink(int pageSize) { |
|||
this(pageSize, 0); |
|||
} |
|||
|
|||
public PageLink(int pageSize, int page) { |
|||
this(pageSize, page, null, null); |
|||
} |
|||
|
|||
public PageLink(int pageSize, int page, String textSearch) { |
|||
this(pageSize, page, textSearch, null); |
|||
} |
|||
|
|||
public PageLink(int pageSize, int page, String textSearch, SortOrder sortOrder) { |
|||
this.pageSize = pageSize; |
|||
this.page = page; |
|||
this.textSearch = textSearch; |
|||
this.sortOrder = sortOrder; |
|||
} |
|||
|
|||
@JsonIgnore |
|||
public PageLink nextPageLink() { |
|||
return new PageLink(this.pageSize, this.page+1, this.textSearch, this.sortOrder); |
|||
} |
|||
|
|||
} |
|||
@ -1,71 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.common.data.page; |
|||
|
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import org.thingsboard.server.common.data.SearchTextBased; |
|||
import org.thingsboard.server.common.data.id.UUIDBased; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
|
|||
public class TextPageData<T extends SearchTextBased<? extends UUIDBased>> { |
|||
|
|||
private final List<T> data; |
|||
private final TextPageLink nextPageLink; |
|||
private final boolean hasNext; |
|||
|
|||
public TextPageData(List<T> data, TextPageLink pageLink) { |
|||
super(); |
|||
this.data = data; |
|||
int limit = pageLink.getLimit(); |
|||
if (data != null && data.size() == limit) { |
|||
int index = data.size()-1; |
|||
UUID idOffset = data.get(index).getId().getId(); |
|||
String textOffset = data.get(index).getSearchText(); |
|||
nextPageLink = new TextPageLink(limit, pageLink.getTextSearch(), idOffset, textOffset); |
|||
hasNext = true; |
|||
} else { |
|||
nextPageLink = null; |
|||
hasNext = false; |
|||
} |
|||
} |
|||
|
|||
@JsonCreator |
|||
public TextPageData(@JsonProperty("data") List<T> data, |
|||
@JsonProperty("nextPageLink") TextPageLink nextPageLink, |
|||
@JsonProperty("hasNext") boolean hasNext) { |
|||
this.data = data; |
|||
this.nextPageLink = nextPageLink; |
|||
this.hasNext = hasNext; |
|||
} |
|||
|
|||
public List<T> getData() { |
|||
return data; |
|||
} |
|||
|
|||
@JsonProperty("hasNext") |
|||
public boolean hasNext() { |
|||
return hasNext; |
|||
} |
|||
|
|||
public TextPageLink getNextPageLink() { |
|||
return nextPageLink; |
|||
} |
|||
|
|||
} |
|||
@ -1,80 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.common.data.page; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonCreator; |
|||
import com.fasterxml.jackson.annotation.JsonProperty; |
|||
import lombok.Getter; |
|||
import lombok.ToString; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.Arrays; |
|||
import java.util.UUID; |
|||
|
|||
@ToString |
|||
public class TextPageLink extends BasePageLink implements Serializable { |
|||
|
|||
private static final long serialVersionUID = -4189954843653250480L; |
|||
|
|||
@Getter private final String textSearch; |
|||
@Getter private final String textSearchBound; |
|||
@Getter private final String textOffset; |
|||
|
|||
public TextPageLink(int limit) { |
|||
this(limit, null, null, null); |
|||
} |
|||
|
|||
public TextPageLink(int limit, String textSearch) { |
|||
this(limit, textSearch, null, null); |
|||
} |
|||
|
|||
public TextPageLink(int limit, String textSearch, UUID idOffset, String textOffset) { |
|||
super(limit, idOffset); |
|||
this.textSearch = textSearch != null ? textSearch.toLowerCase() : null; |
|||
this.textSearchBound = nextSequence(this.textSearch); |
|||
this.textOffset = textOffset != null ? textOffset.toLowerCase() : null; |
|||
} |
|||
|
|||
@JsonCreator |
|||
public TextPageLink(@JsonProperty("limit") int limit, |
|||
@JsonProperty("textSearch") String textSearch, |
|||
@JsonProperty("textSearchBound") String textSearchBound, |
|||
@JsonProperty("textOffset") String textOffset, |
|||
@JsonProperty("idOffset") UUID idOffset) { |
|||
super(limit, idOffset); |
|||
this.textSearch = textSearch; |
|||
this.textSearchBound = textSearchBound; |
|||
this.textOffset = textOffset; |
|||
this.idOffset = idOffset; |
|||
} |
|||
|
|||
private static String nextSequence(String input) { |
|||
if (input != null && input.length() > 0) { |
|||
char[] chars = input.toCharArray(); |
|||
int i = chars.length - 1; |
|||
while (i >= 0 && ++chars[i--] == Character.MIN_VALUE) ; |
|||
if (i == -1 && (chars.length == 0 || chars[0] == Character.MIN_VALUE)) { |
|||
char buf[] = Arrays.copyOf(input.toCharArray(), input.length() + 1); |
|||
buf[buf.length - 1] = Character.MIN_VALUE; |
|||
return new String(buf); |
|||
} |
|||
return new String(chars); |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.dao; |
|||
|
|||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; |
|||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; |
|||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; |
|||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.thingsboard.server.dao.util.NoSqlDao; |
|||
|
|||
@Configuration |
|||
@EnableAutoConfiguration( |
|||
exclude = { |
|||
DataSourceAutoConfiguration.class, |
|||
DataSourceTransactionManagerAutoConfiguration.class, |
|||
HibernateJpaAutoConfiguration.class}) |
|||
@NoSqlDao |
|||
public class NoSqlDaoConfig { |
|||
} |
|||
@ -1,195 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.dao.nosql; |
|||
|
|||
import com.datastax.driver.core.ResultSet; |
|||
import com.datastax.driver.core.ResultSetFuture; |
|||
import com.datastax.driver.core.Statement; |
|||
import com.datastax.driver.core.querybuilder.QueryBuilder; |
|||
import com.datastax.driver.core.querybuilder.Select; |
|||
import com.datastax.driver.core.utils.UUIDs; |
|||
import com.datastax.driver.mapping.Mapper; |
|||
import com.datastax.driver.mapping.Result; |
|||
import com.google.common.base.Function; |
|||
import com.google.common.util.concurrent.Futures; |
|||
import com.google.common.util.concurrent.ListenableFuture; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.dao.Dao; |
|||
import org.thingsboard.server.dao.DaoUtil; |
|||
import org.thingsboard.server.dao.model.BaseEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
import org.thingsboard.server.dao.model.wrapper.EntityResultSet; |
|||
|
|||
import javax.annotation.Nullable; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; |
|||
import static com.datastax.driver.core.querybuilder.QueryBuilder.select; |
|||
|
|||
@Slf4j |
|||
public abstract class CassandraAbstractModelDao<E extends BaseEntity<D>, D> extends CassandraAbstractDao implements Dao<D> { |
|||
|
|||
protected abstract Class<E> getColumnFamilyClass(); |
|||
|
|||
protected abstract String getColumnFamilyName(); |
|||
|
|||
protected E updateSearchTextIfPresent(E entity) { |
|||
return entity; |
|||
} |
|||
|
|||
protected Mapper<E> getMapper() { |
|||
return cluster.getMapper(getColumnFamilyClass()); |
|||
} |
|||
|
|||
protected List<E> findListByStatement(TenantId tenantId, Statement statement) { |
|||
List<E> list = Collections.emptyList(); |
|||
if (statement != null) { |
|||
statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); |
|||
ResultSet resultSet = executeRead(tenantId, statement); |
|||
Result<E> result = getMapper().map(resultSet); |
|||
if (result != null) { |
|||
list = result.all(); |
|||
} |
|||
} |
|||
return list; |
|||
} |
|||
|
|||
protected ListenableFuture<List<D>> findListByStatementAsync(TenantId tenantId, Statement statement) { |
|||
if (statement != null) { |
|||
statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); |
|||
ResultSetFuture resultSetFuture = executeAsyncRead(tenantId, statement); |
|||
return Futures.transform(resultSetFuture, new Function<ResultSet, List<D>>() { |
|||
@Nullable |
|||
@Override |
|||
public List<D> apply(@Nullable ResultSet resultSet) { |
|||
Result<E> result = getMapper().map(resultSet); |
|||
if (result != null) { |
|||
List<E> entities = result.all(); |
|||
return DaoUtil.convertDataList(entities); |
|||
} else { |
|||
return Collections.emptyList(); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
return Futures.immediateFuture(Collections.emptyList()); |
|||
} |
|||
|
|||
protected E findOneByStatement(TenantId tenantId, Statement statement) { |
|||
E object = null; |
|||
if (statement != null) { |
|||
statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); |
|||
ResultSet resultSet = executeRead(tenantId, statement); |
|||
Result<E> result = getMapper().map(resultSet); |
|||
if (result != null) { |
|||
object = result.one(); |
|||
} |
|||
} |
|||
return object; |
|||
} |
|||
|
|||
protected ListenableFuture<D> findOneByStatementAsync(TenantId tenantId, Statement statement) { |
|||
if (statement != null) { |
|||
statement.setConsistencyLevel(cluster.getDefaultReadConsistencyLevel()); |
|||
ResultSetFuture resultSetFuture = executeAsyncRead(tenantId, statement); |
|||
return Futures.transform(resultSetFuture, new Function<ResultSet, D>() { |
|||
@Nullable |
|||
@Override |
|||
public D apply(@Nullable ResultSet resultSet) { |
|||
Result<E> result = getMapper().map(resultSet); |
|||
if (result != null) { |
|||
E entity = result.one(); |
|||
return DaoUtil.getData(entity); |
|||
} else { |
|||
return null; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
return Futures.immediateFuture(null); |
|||
} |
|||
|
|||
protected Statement getSaveQuery(E dto) { |
|||
return getMapper().saveQuery(dto); |
|||
} |
|||
|
|||
protected EntityResultSet<E> saveWithResult(TenantId tenantId, E entity) { |
|||
log.debug("Save entity {}", entity); |
|||
if (entity.getId() == null) { |
|||
entity.setId(UUIDs.timeBased()); |
|||
} else if (isDeleteOnSave()) { |
|||
removeById(tenantId, entity.getId()); |
|||
} |
|||
Statement saveStatement = getSaveQuery(entity); |
|||
saveStatement.setConsistencyLevel(cluster.getDefaultWriteConsistencyLevel()); |
|||
ResultSet resultSet = executeWrite(tenantId, saveStatement); |
|||
return new EntityResultSet<>(resultSet, entity); |
|||
} |
|||
|
|||
protected boolean isDeleteOnSave() { |
|||
return true; |
|||
} |
|||
|
|||
@Override |
|||
public D save(TenantId tenantId, D domain) { |
|||
E entity; |
|||
try { |
|||
entity = getColumnFamilyClass().getConstructor(domain.getClass()).newInstance(domain); |
|||
} catch (Exception e) { |
|||
log.error("Can't create entity for domain object {}", domain, e); |
|||
throw new IllegalArgumentException("Can't create entity for domain object {" + domain + "}", e); |
|||
} |
|||
entity = updateSearchTextIfPresent(entity); |
|||
log.debug("Saving entity {}", entity); |
|||
entity = saveWithResult(tenantId, entity).getEntity(); |
|||
return DaoUtil.getData(entity); |
|||
} |
|||
|
|||
@Override |
|||
public D findById(TenantId tenantId, UUID key) { |
|||
log.debug("Get entity by key {}", key); |
|||
Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); |
|||
log.trace("Execute query {}", query); |
|||
E entity = findOneByStatement(tenantId, query); |
|||
return DaoUtil.getData(entity); |
|||
} |
|||
|
|||
@Override |
|||
public ListenableFuture<D> findByIdAsync(TenantId tenantId, UUID key) { |
|||
log.debug("Get entity by key {}", key); |
|||
Select.Where query = select().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); |
|||
log.trace("Execute query {}", query); |
|||
return findOneByStatementAsync(tenantId, query); |
|||
} |
|||
|
|||
@Override |
|||
public boolean removeById(TenantId tenantId, UUID key) { |
|||
Statement delete = QueryBuilder.delete().all().from(getColumnFamilyName()).where(eq(ModelConstants.ID_PROPERTY, key)); |
|||
log.debug("Remove request: {}", delete.toString()); |
|||
return executeWrite(tenantId, delete).wasApplied(); |
|||
} |
|||
|
|||
@Override |
|||
public List<D> find(TenantId tenantId) { |
|||
log.debug("Get all entities from column family {}", getColumnFamilyName()); |
|||
List<E> entities = findListByStatement(tenantId, QueryBuilder.select().all().from(getColumnFamilyName()).setConsistencyLevel(cluster.getDefaultReadConsistencyLevel())); |
|||
return DaoUtil.convertDataList(entities); |
|||
} |
|||
|
|||
} |
|||
@ -1,83 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.dao.nosql; |
|||
|
|||
import com.datastax.driver.core.querybuilder.Clause; |
|||
import com.datastax.driver.core.querybuilder.QueryBuilder; |
|||
import com.datastax.driver.core.querybuilder.Select; |
|||
import com.datastax.driver.core.querybuilder.Select.Where; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.commons.lang3.StringUtils; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.page.TextPageLink; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
import org.thingsboard.server.dao.model.SearchTextEntity; |
|||
|
|||
import java.util.List; |
|||
|
|||
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; |
|||
import static com.datastax.driver.core.querybuilder.QueryBuilder.select; |
|||
|
|||
@Slf4j |
|||
public abstract class CassandraAbstractSearchTextDao<E extends SearchTextEntity<D>, D> extends CassandraAbstractModelDao<E, D> { |
|||
|
|||
@Override |
|||
protected E updateSearchTextIfPresent(E entity) { |
|||
if (entity.getSearchTextSource() != null) { |
|||
entity.setSearchText(entity.getSearchTextSource().toLowerCase()); |
|||
} else { |
|||
log.trace("Entity [{}] has null SearchTextSource", entity); |
|||
} |
|||
return entity; |
|||
} |
|||
|
|||
protected List<E> findPageWithTextSearch(TenantId tenantId, String searchView, List<Clause> clauses, TextPageLink pageLink) { |
|||
Select select = select().from(searchView); |
|||
Where query = select.where(); |
|||
for (Clause clause : clauses) { |
|||
query.and(clause); |
|||
} |
|||
query.limit(pageLink.getLimit()); |
|||
if (!StringUtils.isEmpty(pageLink.getTextOffset())) { |
|||
query.and(eq(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset())); |
|||
query.and(QueryBuilder.lt(ModelConstants.ID_PROPERTY, pageLink.getIdOffset())); |
|||
List<E> result = findListByStatement(tenantId, query); |
|||
if (result.size() < pageLink.getLimit()) { |
|||
select = select().from(searchView); |
|||
query = select.where(); |
|||
for (Clause clause : clauses) { |
|||
query.and(clause); |
|||
} |
|||
query.and(QueryBuilder.gt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextOffset())); |
|||
if (!StringUtils.isEmpty(pageLink.getTextSearch())) { |
|||
query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound())); |
|||
} |
|||
int limit = pageLink.getLimit() - result.size(); |
|||
query.limit(limit); |
|||
result.addAll(findListByStatement(tenantId, query)); |
|||
} |
|||
return result; |
|||
} else if (!StringUtils.isEmpty(pageLink.getTextSearch())) { |
|||
query.and(QueryBuilder.gte(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearch())); |
|||
query.and(QueryBuilder.lt(ModelConstants.SEARCH_TEXT_PROPERTY, pageLink.getTextSearchBound())); |
|||
return findListByStatement(tenantId, query); |
|||
} else { |
|||
return findListByStatement(tenantId, query); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
|||
@ -1,107 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2019 The Thingsboard 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 |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0
|
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES 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.thingsboard.server.dao.nosql; |
|||
|
|||
import com.datastax.driver.core.querybuilder.Clause; |
|||
import com.datastax.driver.core.querybuilder.Ordering; |
|||
import com.datastax.driver.core.querybuilder.QueryBuilder; |
|||
import com.datastax.driver.core.querybuilder.Select; |
|||
import com.datastax.driver.core.querybuilder.Select.Where; |
|||
import com.datastax.driver.core.utils.UUIDs; |
|||
import org.thingsboard.server.common.data.id.TenantId; |
|||
import org.thingsboard.server.common.data.page.TimePageLink; |
|||
import org.thingsboard.server.dao.model.BaseEntity; |
|||
import org.thingsboard.server.dao.model.ModelConstants; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.Collections; |
|||
import java.util.List; |
|||
import java.util.UUID; |
|||
|
|||
import static com.datastax.driver.core.querybuilder.QueryBuilder.select; |
|||
|
|||
public abstract class CassandraAbstractSearchTimeDao<E extends BaseEntity<D>, D> extends CassandraAbstractModelDao<E, D> { |
|||
|
|||
|
|||
protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, TimePageLink pageLink) { |
|||
return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.emptyList(), pageLink); |
|||
} |
|||
|
|||
protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, Ordering ordering, TimePageLink pageLink) { |
|||
return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.singletonList(ordering), pageLink); |
|||
} |
|||
|
|||
protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink) { |
|||
return findPageWithTimeSearch(tenantId, searchView, clauses, topLevelOrderings, pageLink, ModelConstants.ID_PROPERTY); |
|||
} |
|||
|
|||
protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) { |
|||
return findPageWithTimeSearch(tenantId, searchView, clauses, Collections.emptyList(), pageLink, idColumn); |
|||
} |
|||
|
|||
protected List<E> findPageWithTimeSearch(TenantId tenantId, String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink, String idColumn) { |
|||
return findListByStatement(tenantId, buildQuery(searchView, clauses, topLevelOrderings, pageLink, idColumn)); |
|||
} |
|||
|
|||
public static Where buildQuery(String searchView, List<Clause> clauses, TimePageLink pageLink, String idColumn) { |
|||
return buildQuery(searchView, clauses, Collections.emptyList(), pageLink, idColumn); |
|||
} |
|||
|
|||
public static Where buildQuery(String searchView, List<Clause> clauses, Ordering order, TimePageLink pageLink, String idColumn) { |
|||
return buildQuery(searchView, clauses, Collections.singletonList(order), pageLink, idColumn); |
|||
} |
|||
|
|||
public static Where buildQuery(String searchView, List<Clause> clauses, List<Ordering> topLevelOrderings, TimePageLink pageLink, String idColumn) { |
|||
Select select = select().from(searchView); |
|||
Where query = select.where(); |
|||
for (Clause clause : clauses) { |
|||
query.and(clause); |
|||
} |
|||
query.limit(pageLink.getLimit()); |
|||
if (pageLink.isAscOrder()) { |
|||
if (pageLink.getIdOffset() != null) { |
|||
query.and(QueryBuilder.gt(idColumn, pageLink.getIdOffset())); |
|||
} else if (pageLink.getStartTime() != null) { |
|||
final UUID startOf = UUIDs.startOf(pageLink.getStartTime()); |
|||
query.and(QueryBuilder.gte(idColumn, startOf)); |
|||
} |
|||
if (pageLink.getEndTime() != null) { |
|||
final UUID endOf = UUIDs.endOf(pageLink.getEndTime()); |
|||
query.and(QueryBuilder.lte(idColumn, endOf)); |
|||
} |
|||
} else { |
|||
if (pageLink.getIdOffset() != null) { |
|||
query.and(QueryBuilder.lt(idColumn, pageLink.getIdOffset())); |
|||
} else if (pageLink.getEndTime() != null) { |
|||
final UUID endOf = UUIDs.endOf(pageLink.getEndTime()); |
|||
query.and(QueryBuilder.lte(idColumn, endOf)); |
|||
} |
|||
if (pageLink.getStartTime() != null) { |
|||
final UUID startOf = UUIDs.startOf(pageLink.getStartTime()); |
|||
query.and(QueryBuilder.gte(idColumn, startOf)); |
|||
} |
|||
} |
|||
List<Ordering> orderings = new ArrayList<>(topLevelOrderings); |
|||
if (pageLink.isAscOrder()) { |
|||
orderings.add(QueryBuilder.asc(idColumn)); |
|||
} else { |
|||
orderings.add(QueryBuilder.desc(idColumn)); |
|||
} |
|||
query.orderBy(orderings.toArray(new Ordering[orderings.size()])); |
|||
return query; |
|||
} |
|||
|
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue