@@ -81,7 +81,7 @@ private void dispatchSearchQuery(String query) {
searchSubscription.dispose();

searchSubscription = DataProvider.getInstance(getApplicationContext())
.flatMap(dataProvider -> dataProvider.observeNameQuery(query))
.flatMap(dataProvider -> dataProvider.observeNameQuery(query).toObservable()) // TODO : rm toObservable
.observeOn(AndroidSchedulers.mainThread())
.subscribe(playaItems -> {
// TODO : Send to adapter
@@ -34,6 +34,7 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.Single;
import retrofit2.Retrofit;
@@ -104,7 +105,7 @@ public SimpleLifeboat(@NonNull Table table) {

@Override
public Observable<Boolean> saveData(DataProvider provider) {
Observable<? extends List<? extends com.gaiagps.iburn.database.PlayaItem>> items = null;
Flowable<? extends List<? extends com.gaiagps.iburn.database.PlayaItem>> items = null;

if (table == Table.Camp) {
items = provider.observeCampFavorites();
@@ -5,6 +5,7 @@ import com.gaiagps.iburn.database.Art.Companion.ColAudioTourUrl
import com.gaiagps.iburn.database.Art.Companion.TableName
import com.gaiagps.iburn.database.PlayaItem.Companion.ColFavorite
import com.gaiagps.iburn.database.PlayaItem.Companion.ColName
import io.reactivex.Flowable
import io.reactivex.Observable

/**
@@ -42,16 +43,18 @@ class Art(
interface ArtDao {

@Query("SELECT * FROM $TableName")
fun getAll(): Observable<List<Art>>
fun getAll(): Flowable<List<Art>>

@Query("SELECT * FROM $TableName WHERE $ColAudioTourUrl IS NOT NULL")
fun getAllWithAudioTour(): Observable<List<Art>>
fun getAllWithAudioTour(): Flowable<List<Art>>

@Query("SELECT * FROM $TableName WHERE $ColFavorite = 1")
fun getFavorites(): Observable<List<Art>>
fun getFavorites(): Flowable<List<Art>>

@Query("SELECT * FROM $TableName WHERE $ColName LIKE :name")
fun findByName(name: String): Observable<List<Art>>
// TODO : 'p0' is used vs 'name' b/c Kotlin isn't preserving function parameter names properly
// https://youtrack.jetbrains.com/issue/KT-17959
// @Query("SELECT * FROM $TableName WHERE $ColName LIKE :p0")
// fun findByName(name: String): Flowable<List<Art>>

@Insert
fun insert(vararg art: Art)
@@ -39,13 +39,15 @@ class Camp(
interface CampDao {

@Query("SELECT * FROM $TableName")
fun getAll(): Observable<List<Camp>>
fun getAll(): Flowable<List<Camp>>

@Query("SELECT * FROM $TableName WHERE $ColFavorite = 1")
fun getFavorites(): Observable<List<Camp>>
fun getFavorites(): Flowable<List<Camp>>

@Query("SELECT * FROM $TableName WHERE $ColName LIKE :name")
fun findByName(name: String): Observable<List<Camp>>
// TODO : 'p0' is used vs 'name' b/c Kotlin isn't preserving function parameter names properly
// https://youtrack.jetbrains.com/issue/KT-17959
// @Query("SELECT * FROM $TableName WHERE $ColName LIKE :p0")
// fun findByName(name: String): Flowable<List<Camp>>

@Insert
fun insert(vararg camps: Camp)
@@ -9,11 +9,14 @@
import com.gaiagps.iburn.Constants;
import com.gaiagps.iburn.PrefsHelper;

import org.intellij.lang.annotations.Flow;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
@@ -121,21 +124,22 @@ public int deleteCamps() {
// if (result != null) result.close();
}

public Observable<List<Camp>> observeCamps() {
public Flowable<List<Camp>> observeCamps() {
return db.campDao().getAll();
}

public Observable<List<Camp>> observeCampFavorites() {
public Flowable<List<Camp>> observeCampFavorites() {

// TODO : Honor upgradeLock?
return db.campDao().getFavorites();
}

public Observable<List<Camp>> observeCampsByName(@NonNull String query) {
public Flowable<List<Camp>> observeCampsByName(@NonNull String query) {

// TODO : Honor upgradeLock
// TODO : Return structure with metadata on how many art, camps, events etc?
return db.campDao().findByName(query);
// return db.campDao().findByName(query);
return Flowable.empty();
}

// TODO : Replace with Table-specific queries
@@ -183,7 +187,7 @@ public void endTransaction() {
}

public void insert(@NonNull String table, @NonNull ContentValues values) {
db.getOpenHelper().getWritableDatabase().insert(table, null, values);
db.getOpenHelper().getWritableDatabase().insert(table, 0, values); // TODO : wtf is the int here?
}

public int delete(@NonNull String table) {
@@ -238,18 +242,19 @@ public int deleteEvents() {
// if (result != null) result.close();
}

public Observable<List<Event>> observeEventsOnDayOfTypes(@NonNull String day,
public Flowable<List<Event>> observeEventsOnDayOfTypes(@NonNull String day,
@Nullable ArrayList<String> types) {

// TODO : Honor upgradeLock?
if (types == null) {
return db.eventDao().findByDay(day);
} else {
return db.eventDao().findByDayAndType(day, types);
}
// if (types == null) {
// return db.eventDao().findByDay(day);
// } else {
// return db.eventDao().findByDayAndType(day, types);
// }
return Flowable.empty();
}

public Observable<List<Event>> observeEventFavorites() {
public Flowable<List<Event>> observeEventFavorites() {

// TODO : Honor upgradeLock?
return db.eventDao().getFavorites();
@@ -261,19 +266,19 @@ public int deleteArt() {
// if (result != null) result.close();
}

public Observable<List<Art>> observeArt() {
public Flowable<List<Art>> observeArt() {

// TODO : Honor upgradeLock?
return db.artDao().getAll();
}

public Observable<List<Art>> observeArtFavorites() {
public Flowable<List<Art>> observeArtFavorites() {

// TODO : Honor upgradeLock?
return db.artDao().getFavorites();
}

public Observable<List<Art>> observeArtWithAudioTour() {
public Flowable<List<Art>> observeArtWithAudioTour() {

// TODO : Honor upgradeLock?
return db.artDao().getAllWithAudioTour();
@@ -285,11 +290,11 @@ public Observable<List<Art>> observeArtWithAudioTour() {
* Note: This query automatically adds in Event.startTime (and 0 values for all non-events),
* since we always want to show this data for an event.
*/
public Observable<List<PlayaItem>> observeFavorites() {
public Flowable<List<PlayaItem>> observeFavorites() {

// TODO : Honor upgradeLock
// TODO : Return structure with metadata on how many art, camps, events etc?
return Observable.zip(
return Flowable.zip(
db.artDao().getFavorites(),
db.campDao().getFavorites(),
db.eventDao().getFavorites(),
@@ -309,22 +314,23 @@ public Observable<List<PlayaItem>> observeFavorites() {
* Note: This query automatically adds in Event.startTime (and 0 values for all non-events),
* since we always want to show this data for an event.
*/
public Observable<List<PlayaItem>> observeNameQuery(@NonNull String query) {
public Flowable<List<PlayaItem>> observeNameQuery(@NonNull String query) {

// TODO : Honor upgradeLock
// TODO : Return structure with metadata on how many art, camps, events etc?
return Observable.zip(
db.artDao().findByName(query),
db.campDao().findByName(query),
db.eventDao().findByName(query),
(arts, camps, events) -> {
ArrayList<PlayaItem> all = new ArrayList<>(arts.size() + camps.size() + events.size());
all.addAll(arts);
all.addAll(camps);
all.addAll(events);
return all;
}
);
// return Flowable.zip(
// db.artDao().findByName(query),
// db.campDao().findByName(query),
// db.eventDao().findByName(query),
// (arts, camps, events) -> {
// ArrayList<PlayaItem> all = new ArrayList<>(arts.size() + camps.size() + events.size());
// all.addAll(arts);
// all.addAll(camps);
// all.addAll(events);
// return all;
// }
// );
return Flowable.empty();
}

private void update(@NonNull PlayaItem item) {
@@ -6,6 +6,8 @@ import com.gaiagps.iburn.database.Event.Companion.ColStartTime
import com.gaiagps.iburn.database.Event.Companion.ColStartTimePretty
import com.gaiagps.iburn.database.Event.Companion.ColType
import com.gaiagps.iburn.database.Event.Companion.TableName
import com.gaiagps.iburn.database.PlayaItem.Companion.ColName
import io.reactivex.Flowable
import io.reactivex.Observable
import java.util.*

@@ -52,24 +54,26 @@ class Event(

@Dao
interface EventDao {
// TODO : 'p0' is used vs 'name' b/c Kotlin isn't preserving function parameter names properly
// https://youtrack.jetbrains.com/issue/KT-17959

@Query("SELECT * FROM $TableName")
fun getAll(): Observable<List<Event>>
fun getAll(): Flowable<List<Event>>

@Query("SELECT * FROM $TableName")
fun getFavorites(): Observable<List<Event>>
fun getFavorites(): Flowable<List<Event>>

@Query("SELECT * FROM $TableName WHERE $ColCampPlayaId = :campPlayaId ORDER BY $ColStartTime")
fun findByCampPlayaId(campPlayaId: Int): Observable<List<Event>>
// @Query("SELECT * FROM $TableName WHERE $ColCampPlayaId = :p0 ORDER BY $ColStartTime")
// fun findByCampPlayaId(campPlayaId: Int): Flowable<List<Event>>

@Query("SELECT * FROM $TableName WHERE $ColStartTimePretty LIKE :day% ORDER BY $ColStartTime")
fun findByDay(day: String): Observable<List<Event>>
// @Query("SELECT * FROM $TableName WHERE $ColStartTimePretty LIKE :p0 ORDER BY $ColStartTime")
// fun findByDay(day: String): Flowable<List<Event>>

@Query("SELECT * FROM $TableName WHERE ( start_time_pretty LIKE :day% AND $ColType IN (:types) ) ORDER BY $ColStartTime")
fun findByDayAndType(day: String, types: List<String>): Observable<List<Event>>
// @Query("SELECT * FROM $TableName WHERE ( start_time_pretty LIKE :day% AND $ColType IN (:types) ) ORDER BY $ColStartTime")
// fun findByDayAndType(day: String, types: List<String>): Flowable<List<Event>>

@Query("SELECT * FROM $TableName WHERE name LIKE :name GROUP BY $") // GROUP_BY name eliminates duplicate entries for separate occurrences
fun findByName(name: String): Observable<List<Event>>
// @Query("SELECT * FROM $TableName WHERE $ColName LIKE :p0 GROUP BY $ColName") // GROUP_BY name eliminates duplicate entries for separate occurrences
// fun findByName(name: String): Flowable<List<Event>>

@Insert
fun insert(vararg event: Event)
@@ -16,7 +16,7 @@ abstract class PlayaItem(
@ColumnInfo(name = ColContact) val contact: String,
@ColumnInfo(name = ColPlayaAddress) val playaAddress: String?,
@ColumnInfo(name = ColPlayaId) val playaId: String,
@Embedded @ColumnInfo(name = ColLocation) val location: Location,
@Embedded val location: Location,
@ColumnInfo(name = ColFavorite) val isFavorite: Boolean) : Serializable {

companion object {
@@ -27,7 +27,6 @@ abstract class PlayaItem(
const val ColContact = "contact"
const val ColPlayaAddress = "playa_address"
const val ColPlayaId = "playa_id"
const val ColLocation = "location"
const val ColFavorite = "favorite"
}
}
@@ -35,9 +35,9 @@ public Disposable createDisposable() {
return DataProvider.getInstance(getActivity().getApplicationContext())
.flatMap(dataProvider -> {
if (showAudioTourOnly) {
return dataProvider.observeArtWithAudioTour();
return dataProvider.observeArtWithAudioTour().toObservable(); // TODO : Rm toObservable
} else {
return dataProvider.observeArt();
return dataProvider.observeArt().toObservable(); // TODO : Rm toObservable
}
})
.observeOn(AndroidSchedulers.mainThread())
@@ -61,25 +61,25 @@ protected Disposable createDisposable() {

case CAMPS:
playaItems = dataProvider
.flatMap(DataProvider::observeCamps);
.flatMap(dataProvider1 -> dataProvider1.observeCamps().toObservable()); // TODO : rm toObservable

break;

case ART:
playaItems = dataProvider
.flatMap(dp -> {
if (showAudioTourOnly) {
return dp.observeArtWithAudioTour();
return dp.observeArtWithAudioTour().toObservable();
} else {
return dp.observeArt();
return dp.observeArt().toObservable();
}
});

break;

case EVENT:
playaItems = dataProvider
.flatMap(dp -> dp.observeEventsOnDayOfTypes(selectedDay, selectedTypes));
.flatMap(dp -> dp.observeEventsOnDayOfTypes(selectedDay, selectedTypes).toObservable());

break;
}
@@ -22,7 +22,7 @@ public static CampListViewFragment newInstance() {
@Override
public Disposable createDisposable() {
return DataProvider.getInstance(getActivity().getApplicationContext())
.flatMap(dataProvider -> dataProvider.observeCamps())
.flatMap(dataProvider -> dataProvider.observeCamps().toObservable()) // TODO : Rm toObservable
.doOnNext(query -> Timber.d("Got query"))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(cursor -> {
@@ -40,7 +40,7 @@ public static EventListViewFragment newInstance() {
@Override
public Disposable createDisposable() {
return DataProvider.getInstance(getActivity().getApplicationContext())
.flatMap(dataProvider -> dataProvider.observeEventsOnDayOfTypes(selectedDay, selectedTypes))
.flatMap(dataProvider -> dataProvider.observeEventsOnDayOfTypes(selectedDay, selectedTypes).toObservable()) // TODO : RM toObservable
.observeOn(AndroidSchedulers.mainThread())
.subscribe(events -> {
Timber.d("Data onNext %d items", events.size());
@@ -48,7 +48,7 @@ public Disposable createDisposable() {
// Get Events that start now to the next several hours
return DataProvider.getInstance(getActivity().getApplicationContext())
.subscribeOn(Schedulers.computation())
.flatMap(dataProvider -> dataProvider.observeEventFavorites())//dataProvider.createQuery(PlayaDatabase.EVENTS, "SELECT " + DataProvider.makeProjectionString(adapter.getRequiredProjection()) + " FROM " + PlayaDatabase.EVENTS + " WHERE " + EventTable.startTime + " > '" + lowerBoundDateStr + "' AND " + EventTable.startTime + " < '" + upperBoundDateStr + "\' ORDER BY " + EventTable.startTime + " ASC LIMIT 100"))
.flatMap(dataProvider -> dataProvider.observeEventFavorites().toObservable()) // TODO : rm toObservabe //dataProvider.createQuery(PlayaDatabase.EVENTS, "SELECT " + DataProvider.makeProjectionString(adapter.getRequiredProjection()) + " FROM " + PlayaDatabase.EVENTS + " WHERE " + EventTable.startTime + " > '" + lowerBoundDateStr + "' AND " + EventTable.startTime + " < '" + upperBoundDateStr + "\' ORDER BY " + EventTable.startTime + " ASC LIMIT 100"))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(events -> {
Timber.d("Data onNext %d items", events.size());
@@ -40,7 +40,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
protected Disposable createDisposable() {

return DataProvider.getInstance(getActivity().getApplicationContext())
.flatMap(DataProvider::observeFavorites)
.flatMap(provider -> provider.observeFavorites().toObservable()) // TODO : rm toObservable
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onDataChanged, throwable -> Timber.e(throwable, "Failed to load favorites"));
}
@@ -97,9 +97,10 @@ public void onSearchQueryRequested(String query) {
mState = STATE.SEARCH;
// TODO : Do we monitor query or just take first result?
// TODO : Do we want to merge search queries into the cameraUpdate subscription in initMap?
DataProvider.getInstance(getActivity().getApplicationContext())
.flatMap(dataProvider -> dataProvider.observeNameQuery(query))
.subscribe(this::processMapItemResult);
// TODO : Fix DB query with parameter
// DataProvider.getInstance(getActivity().getApplicationContext())
// .flatMap(dataProvider -> dataProvider.observeNameQuery(query))
// .subscribe(this::processMapItemResult);
}
}