org.greenrobot.daocompat.query.AbstractQueryData Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of objectbox-daocompat Show documentation
Show all versions of objectbox-daocompat Show documentation
ObjectBox is a fast NoSQL database for Objects
The newest version!
/*
* Copyright (C) 2011-2017 Markus Junginger, greenrobot (http://greenrobot.org)
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES 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.greenrobot.daocompat.query;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.greenrobot.daocompat.AbstractDao;
import org.greenrobot.daocompat.query.QueryBuilder.Condition;
import org.greenrobot.daocompat.query.QueryBuilder.Order;
abstract class AbstractQueryData> {
final AbstractDao dao;
final Condition[] conditions;
final Order[] orders;
final Integer limit;
final Integer offset;
final Map> queriesForThreads;
AbstractQueryData(AbstractDao dao, Condition[] conditions, Order[] orders, Integer limit,
Integer offset) {
this.dao = dao;
this.conditions = conditions;
this.orders = orders;
this.limit = limit;
this.offset = offset;
queriesForThreads = new HashMap<>();
}
/**
* Just an optimized version, which performs faster if the current thread is already the query's owner thread.
* Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.
*/
Q forCurrentThread(Q query) {
if (Thread.currentThread() == query.ownerThread) {
// reset parameters by building new objectbox query
query.objectBoxQuery = buildObjectBoxQuery();
return query;
} else {
return forCurrentThread();
}
}
/**
* Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.
*/
Q forCurrentThread() {
// Process.myTid() seems to have issues on some devices (see Github #376) and Robolectric (#171):
// We use currentThread().getId() instead (unfortunately return a long, can not use SparseArray).
// PS.: thread ID may be reused, which should be fine because old thread will be gone anyway.
long threadId = Thread.currentThread().getId();
synchronized (queriesForThreads) {
WeakReference queryRef = queriesForThreads.get(threadId);
Q query = queryRef != null ? queryRef.get() : null;
if (query == null) {
gc();
query = createQuery();
queriesForThreads.put(threadId, new WeakReference<>(query));
} else {
// reset parameters by building new objectbox query
query.objectBoxQuery = buildObjectBoxQuery();
}
return query;
}
}
protected io.objectbox.query.Query buildObjectBoxQuery() {
io.objectbox.query.QueryBuilder queryBuilder = dao.getBox().query();
for (Condition condition : conditions) {
// Note: no longer can supply string order here, is supplied as part of creating condition.
condition.queryCondition.apply(queryBuilder);
}
for (Order order : orders) {
queryBuilder.order(order.property, order.orderFlag);
}
return queryBuilder.build();
}
abstract protected Q createQuery();
void gc() {
synchronized (queriesForThreads) {
Iterator>> iterator = queriesForThreads.entrySet().iterator();
while (iterator.hasNext()) {
Entry> entry = iterator.next();
if (entry.getValue().get() == null) {
iterator.remove();
}
}
}
}
}