void publish() { box.getStore().internalScheduleThread(new Runnable() { @Override public void run() { List<T> result = query.find(); for (DataObserver<List<T>> observer : observers) { observer.onData(result); } } }); }
@Override public void publishSingle(final DataObserver<List<T>> observer, @Nullable Object param) { box.getStore().internalScheduleThread(new Runnable() { @Override public void run() { List<T> result = query.find(); observer.onData(result); } }); }
Query(Box<T> box, long queryHandle, boolean hasOrder, List<EagerRelation> eagerRelations, QueryFilter<T> filter, Comparator<T> comparator) { this.box = box; store = box.getStore(); queryAttempts = store.internalQueryAttempts(); handle = queryHandle; this.hasOrder = hasOrder; publisher = new QueryPublisher<>(this, box); this.eagerRelations = eagerRelations; this.filter = filter; this.comparator = comparator; }
/** Loads the remaining entities (if any) that were not loaded before. Applies to cached lazy lists only. */ public void loadRemaining() { if (loadedCount != size) { checkCached(); // use single reader only for efficiency box.getStore().runInReadTx(new Runnable() { @Override public void run() { for (int i = 0; i < size; i++) { get(i); } } }); } }
/** * A {@link io.objectbox.reactive.DataObserver} can be subscribed to data changes using the returned builder. * The observer is supplied via {@link SubscriptionBuilder#observer(DataObserver)} and will be notified once * the query results have (potentially) changed. * <p> * With subscribing, the observer will immediately get current query results. * The query is run for the subscribing observer. * <p> * Threading notes: * Query observers are notified from a thread pooled. Observers may be notified in parallel. * The notification order is the same as the subscription order, although this may not always be guaranteed in * the future. * <p> * Stale observers: you must hold on to the Query or {@link io.objectbox.reactive.DataSubscription} objects to keep * your {@link DataObserver}s active. If this Query is not referenced anymore * (along with its {@link io.objectbox.reactive.DataSubscription}s, which hold a reference to the Query internally), * it may be GCed and observers may become stale (won't receive anymore data). */ public SubscriptionBuilder<List<T>> subscribe() { return new SubscriptionBuilder<>(publisher, null, box.getStore().internalThreadPool()); }
public String getReaderDebugInfo() { Cursor<T> reader = getReader(); try { return reader + " with " + reader.getTx() + "; store's commit count: " + getStore().commitCount; } finally { releaseReader(reader); } }
box.getStore().runInReadTx(new Runnable() { @Override public void run() {
@Override public synchronized void subscribe(DataObserver<List<T>> observer, @Nullable Object param) { final BoxStore store = box.getStore(); if (objectClassObserver == null) { objectClassObserver = new DataObserver<Class<T>>() { @Override public void onData(Class<T> objectClass) { publish(); } }; } if (observers.isEmpty()) { if (objectClassSubscription != null) { throw new IllegalStateException("Existing subscription found"); } // Weak: Query references QueryPublisher, which references objectClassObserver. // Query's DataSubscription references QueryPublisher, which references Query. // --> Query and its DataSubscription keep objectClassSubscription alive. // --> If both are gone, the app could not possibly unsubscribe. // --> OK for objectClassSubscription to be GCed and thus unsubscribed? // --> However, still subscribed observers to the query will NOT be notified anymore. objectClassSubscription = store.subscribe(box.getEntityClass()) .weak() .onlyChanges() .observer(objectClassObserver); } observers.add(observer); }