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