From 15282e600a818c2e4d3b5fc21e8a2d5143d818e5 Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Fri, 13 Sep 2013 09:22:41 +0200 Subject: refactoring: cgData -> DataStore --- .../src/cgeo/geocaching/AbstractPopupActivity.java | 2 +- main/src/cgeo/geocaching/CacheCache.java | 2 +- main/src/cgeo/geocaching/CacheDetailActivity.java | 12 +- main/src/cgeo/geocaching/DataStore.java | 3023 ++++++++++++++++++++ main/src/cgeo/geocaching/EditWaypointActivity.java | 14 +- main/src/cgeo/geocaching/Geocache.java | 44 +- main/src/cgeo/geocaching/ImagesActivity.java | 2 +- main/src/cgeo/geocaching/LogCacheActivity.java | 12 +- main/src/cgeo/geocaching/LogTrackableActivity.java | 2 +- main/src/cgeo/geocaching/MainActivity.java | 12 +- .../cgeo/geocaching/NavigateAnyPointActivity.java | 8 +- main/src/cgeo/geocaching/SearchActivity.java | 4 +- main/src/cgeo/geocaching/SearchResult.java | 10 +- main/src/cgeo/geocaching/StaticMapsActivity.java | 4 +- main/src/cgeo/geocaching/StoredList.java | 12 +- main/src/cgeo/geocaching/TrackableActivity.java | 2 +- main/src/cgeo/geocaching/WaypointPopup.java | 2 +- .../apps/cache/navi/AbstractStaticMapsApp.java | 4 +- main/src/cgeo/geocaching/cgData.java | 3023 -------------------- main/src/cgeo/geocaching/cgeoapplication.java | 8 +- main/src/cgeo/geocaching/cgeocaches.java | 22 +- .../cgeo/geocaching/connector/gc/GCConnector.java | 20 +- main/src/cgeo/geocaching/connector/gc/GCMap.java | 6 +- .../src/cgeo/geocaching/connector/gc/GCParser.java | 8 +- .../connector/oc/OCApiLiveConnector.java | 6 +- .../cgeo/geocaching/connector/oc/OkapiClient.java | 6 +- .../cgeo/geocaching/export/FieldnoteExport.java | 4 +- main/src/cgeo/geocaching/export/GpxSerializer.java | 4 +- main/src/cgeo/geocaching/files/GPXImporter.java | 4 +- main/src/cgeo/geocaching/files/GPXParser.java | 12 +- main/src/cgeo/geocaching/files/LocParser.java | 4 +- .../cgeo/geocaching/filter/AttributeFilter.java | 4 +- .../loaders/HistoryGeocacheListLoader.java | 4 +- .../loaders/OfflineGeocacheListLoader.java | 4 +- .../loaders/RemoveFromHistoryLoader.java | 6 +- main/src/cgeo/geocaching/maps/CGeoMap.java | 24 +- main/src/cgeo/geocaching/maps/CachesOverlay.java | 4 +- .../cgeo/geocaching/sorting/FindsComparator.java | 4 +- main/src/cgeo/geocaching/twitter/Twitter.java | 6 +- main/src/cgeo/geocaching/ui/LoggingUI.java | 4 +- .../cgeo/geocaching/utils/DatabaseBackupUtils.java | 10 +- tests/src/cgeo/CGeoTestCase.java | 6 +- tests/src/cgeo/geocaching/DataStoreTest.java | 228 ++ tests/src/cgeo/geocaching/StoredListTest.java | 6 +- tests/src/cgeo/geocaching/cgDataTest.java | 228 -- tests/src/cgeo/geocaching/cgeoApplicationTest.java | 8 +- .../geocaching/connector/gc/WaypointsTest.java | 4 +- .../geocaching/connector/oc/OkapiClientTest.java | 4 +- tests/src/cgeo/geocaching/export/ExportTest.java | 6 +- .../src/cgeo/geocaching/files/GPXImporterTest.java | 26 +- tests/src/cgeo/geocaching/files/GPXParserTest.java | 8 +- .../AbstractResourceInstrumentationTestCase.java | 12 +- 52 files changed, 3452 insertions(+), 3452 deletions(-) create mode 100644 main/src/cgeo/geocaching/DataStore.java delete mode 100644 main/src/cgeo/geocaching/cgData.java create mode 100644 tests/src/cgeo/geocaching/DataStoreTest.java delete mode 100644 tests/src/cgeo/geocaching/cgDataTest.java diff --git a/main/src/cgeo/geocaching/AbstractPopupActivity.java b/main/src/cgeo/geocaching/AbstractPopupActivity.java index 03f0680..da4888f 100644 --- a/main/src/cgeo/geocaching/AbstractPopupActivity.java +++ b/main/src/cgeo/geocaching/AbstractPopupActivity.java @@ -109,7 +109,7 @@ public abstract class AbstractPopupActivity extends AbstractActivity { } protected void init() { - cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); if (cache == null) { showToast(res.getString(R.string.err_detail_cache_find)); diff --git a/main/src/cgeo/geocaching/CacheCache.java b/main/src/cgeo/geocaching/CacheCache.java index e70b7a0..b3c674c 100644 --- a/main/src/cgeo/geocaching/CacheCache.java +++ b/main/src/cgeo/geocaching/CacheCache.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.cgData.StorageLocation; +import cgeo.geocaching.DataStore.StorageLocation; import cgeo.geocaching.connector.gc.Tile; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Viewport; diff --git a/main/src/cgeo/geocaching/CacheDetailActivity.java b/main/src/cgeo/geocaching/CacheDetailActivity.java index e04f7ed..0497a69 100644 --- a/main/src/cgeo/geocaching/CacheDetailActivity.java +++ b/main/src/cgeo/geocaching/CacheDetailActivity.java @@ -493,14 +493,14 @@ public class CacheDetailActivity extends AbstractViewPagerActivity 0) { + db.execSQL("delete from " + dbTableCaches + " where reason = 0"); + + if (oldVersion < 52) { // upgrade to 52 + try { + db.execSQL(dbCreateSearchDestinationHistory); + + Log.i("Added table " + dbTableSearchDestionationHistory + "."); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 52", e); + } + } + + if (oldVersion < 53) { // upgrade to 53 + try { + db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer"); + + Log.i("Column onWatchlist added to " + dbTableCaches + "."); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 53", e); + } + } + + if (oldVersion < 54) { // update to 54 + try { + db.execSQL(dbCreateLogImages); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 54", e); + + } + } + + if (oldVersion < 55) { // update to 55 + try { + db.execSQL("alter table " + dbTableCaches + " add column personal_note text"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 55", e); + } + } + + // make all internal attribute names lowercase + // @see issue #299 + if (oldVersion < 56) { // update to 56 + try { + db.execSQL("update " + dbTableAttributes + " set attribute = " + + "lower(attribute) where attribute like \"%_yes\" " + + "or attribute like \"%_no\""); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 56", e); + } + } + + // Create missing indices. See issue #435 + if (oldVersion < 57) { // update to 57 + try { + db.execSQL("drop index in_a"); + db.execSQL("drop index in_b"); + db.execSQL("drop index in_c"); + db.execSQL("drop index in_d"); + db.execSQL("drop index in_e"); + db.execSQL("drop index in_f"); + createIndices(db); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 57", e); + } + } + + if (oldVersion < 58) { // upgrade to 58 + try { + db.beginTransaction(); + + final String dbTableCachesTemp = dbTableCaches + "_temp"; + final String dbCreateCachesTemp = "" + + "create table " + dbTableCachesTemp + " (" + + "_id integer primary key autoincrement, " + + "updated long not null, " + + "detailed integer not null default 0, " + + "detailedupdate long, " + + "visiteddate long, " + + "geocode text unique not null, " + + "reason integer not null default 0, " + + "cacheid text, " + + "guid text, " + + "type text, " + + "name text, " + + "own integer not null default 0, " + + "owner text, " + + "owner_real text, " + + "hidden long, " + + "hint text, " + + "size text, " + + "difficulty float, " + + "terrain float, " + + "latlon text, " + + "location text, " + + "direction double, " + + "distance double, " + + "latitude double, " + + "longitude double, " + + "reliable_latlon integer, " + + "personal_note text, " + + "shortdesc text, " + + "description text, " + + "favourite_cnt integer, " + + "rating float, " + + "votes integer, " + + "myvote float, " + + "disabled integer not null default 0, " + + "archived integer not null default 0, " + + "members integer not null default 0, " + + "found integer not null default 0, " + + "favourite integer not null default 0, " + + "inventorycoins integer default 0, " + + "inventorytags integer default 0, " + + "inventoryunknown integer default 0, " + + "onWatchlist integer default 0 " + + "); "; + + db.execSQL(dbCreateCachesTemp); + db.execSQL("insert into " + dbTableCachesTemp + " select _id,updated,detailed,detailedupdate,visiteddate,geocode,reason,cacheid,guid,type,name,own,owner,owner_real," + + "hidden,hint,size,difficulty,terrain,latlon,location,direction,distance,latitude,longitude, 0," + + "personal_note,shortdesc,description,favourite_cnt,rating,votes,myvote,disabled,archived,members,found,favourite,inventorycoins," + + "inventorytags,inventoryunknown,onWatchlist from " + dbTableCaches); + db.execSQL("drop table " + dbTableCaches); + db.execSQL("alter table " + dbTableCachesTemp + " rename to " + dbTableCaches); + + final String dbTableWaypointsTemp = dbTableWaypoints + "_temp"; + final String dbCreateWaypointsTemp = "" + + "create table " + dbTableWaypointsTemp + " (" + + "_id integer primary key autoincrement, " + + "geocode text not null, " + + "updated long not null, " // date of save + + "type text not null default 'waypoint', " + + "prefix text, " + + "lookup text, " + + "name text, " + + "latlon text, " + + "latitude double, " + + "longitude double, " + + "note text " + + "); "; + db.execSQL(dbCreateWaypointsTemp); + db.execSQL("insert into " + dbTableWaypointsTemp + " select _id, geocode, updated, type, prefix, lookup, name, latlon, latitude, longitude, note from " + dbTableWaypoints); + db.execSQL("drop table " + dbTableWaypoints); + db.execSQL("alter table " + dbTableWaypointsTemp + " rename to " + dbTableWaypoints); + + createIndices(db); + + db.setTransactionSuccessful(); + + Log.i("Removed latitude_string and longitude_string columns"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 58", e); + } finally { + db.endTransaction(); + } + } + + if (oldVersion < 59) { + try { + // Add new indices and remove obsolete cache files + createIndices(db); + removeObsoleteCacheDirectories(db); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 59", e); + } + } + + if (oldVersion < 60) { + try { + removeSecEmptyDirs(); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 60", e); + } + } + if (oldVersion < 61) { + try { + db.execSQL("alter table " + dbTableLogs + " add column friend integer"); + db.execSQL("alter table " + dbTableCaches + " add column coordsChanged integer default 0"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 61", e); + + } + } + // Introduces finalDefined on caches and own on waypoints + if (oldVersion < 62) { + try { + db.execSQL("alter table " + dbTableCaches + " add column finalDefined integer default 0"); + db.execSQL("alter table " + dbTableWaypoints + " add column own integer default 0"); + db.execSQL("update " + dbTableWaypoints + " set own = 1 where type = 'own'"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 62", e); + + } + } + if (oldVersion < 63) { + try { + removeDoubleUnderscoreMapFiles(); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 63", e); + + } + } + + if (oldVersion < 64) { + try { + // No cache should ever be stored into the ALL_CACHES list. Here we use hardcoded list ids + // rather than symbolic ones because the fix must be applied with the values at the time + // of the problem. The problem was introduced in release 2012.06.01. + db.execSQL("update " + dbTableCaches + " set reason=1 where reason=2"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 64", e); + } + } + + if (oldVersion < 65) { + try { + // Set all waypoints where name is Original coordinates to type ORIGINAL + db.execSQL("update " + dbTableWaypoints + " set type='original', own=0 where name='Original Coordinates'"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 65:", e); + } + } + // Introduces visited feature on waypoints + if (oldVersion < 66) { + try { + db.execSQL("alter table " + dbTableWaypoints + " add column visited integer default 0"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 66", e); + + } + } + // issue2662 OC: Leichtes Klettern / Easy climbing + if (oldVersion < 67) { + try { + db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_yes' where geocode like 'OC%' and attribute = 'climbing_yes'"); + db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_no' where geocode like 'OC%' and attribute = 'climbing_no'"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 67", e); + + } + } + // Introduces logPasswordRequired on caches + if (oldVersion < 68) { + try { + db.execSQL("alter table " + dbTableCaches + " add column logPasswordRequired integer default 0"); + } catch (Exception e) { + Log.e("Failed to upgrade to ver. 68", e); + + } + } + } + + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + } + + Log.i("Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed"); + } + + @Override + public void onOpen(final SQLiteDatabase db) { + if (firstRun) { + sanityChecks(db); + firstRun = false; + } + } + + /** + * Execute sanity checks that should be performed once per application after the database has been + * opened. + * + * @param db the database to perform sanity checks against + */ + private static void sanityChecks(final SQLiteDatabase db) { + // Check that the history of searches is well formed as some dates seem to be missing according + // to NPE traces. + final int staleHistorySearches = db.delete(dbTableSearchDestionationHistory, "date is null", null); + if (staleHistorySearches > 0) { + Log.w(String.format(Locale.getDefault(), "DataStore.dbHelper.onOpen: removed %d bad search history entries", staleHistorySearches)); + } + } + + /** + * Method to remove static map files with double underscore due to issue#1670 + * introduced with release on 2012-05-24. + */ + private static void removeDoubleUnderscoreMapFiles() { + File[] geocodeDirs = LocalStorage.getStorage().listFiles(); + final FilenameFilter filter = new FilenameFilter() { + @Override + public boolean accept(File dir, String filename) { + return filename.startsWith("map_") && filename.contains("__"); + } + }; + for (final File dir : geocodeDirs) { + final File[] wrongFiles = dir.listFiles(filter); + if (wrongFiles != null) { + for (final File wrongFile : wrongFiles) { + FileUtils.deleteIgnoringFailure(wrongFile); + } + } + } + } + } + + /** + * Remove obsolete cache directories in c:geo private storage. + * + * @param db + * the read-write database to use + */ + private static void removeObsoleteCacheDirectories(final SQLiteDatabase db) { + final Pattern oldFilePattern = Pattern.compile("^[GC|TB|O][A-Z0-9]{4,7}$"); + final SQLiteStatement select = db.compileStatement("select count(*) from " + dbTableCaches + " where geocode = ?"); + final File[] files = LocalStorage.getStorage().listFiles(); + final ArrayList toRemove = new ArrayList(files.length); + for (final File file : files) { + if (file.isDirectory()) { + final String geocode = file.getName(); + if (oldFilePattern.matcher(geocode).find()) { + select.bindString(1, geocode); + if (select.simpleQueryForLong() == 0) { + toRemove.add(file); + } + } + } + } + + // Use a background thread for the real removal to avoid keeping the database locked + // if we are called from within a transaction. + new Thread(new Runnable() { + @Override + public void run() { + for (final File dir : toRemove) { + Log.i("Removing obsolete cache directory for " + dir.getName()); + LocalStorage.deleteDirectory(dir); + } + } + }).start(); + } + + /* + * Remove empty directories created in the secondary storage area. + */ + private static void removeSecEmptyDirs() { + for (final File file : LocalStorage.getStorageSec().listFiles()) { + if (file.isDirectory()) { + // This will silently fail if the directory is not empty. + FileUtils.deleteIgnoringFailure(file); + } + } + } + + private static void dropDatabase(SQLiteDatabase db) { + db.execSQL("drop table if exists " + dbTableCaches); + db.execSQL("drop table if exists " + dbTableAttributes); + db.execSQL("drop table if exists " + dbTableWaypoints); + db.execSQL("drop table if exists " + dbTableSpoilers); + db.execSQL("drop table if exists " + dbTableLogs); + db.execSQL("drop table if exists " + dbTableLogCount); + db.execSQL("drop table if exists " + dbTableLogsOffline); + db.execSQL("drop table if exists " + dbTableTrackables); + } + + public static String[] getRecentGeocodesForSearch() { + init(); + + try { + long timestamp = System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED; + final Cursor cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + "(detailed = 1 and detailedupdate > ?) or reason > 0", + new String[]{Long.toString(timestamp)}, + null, + null, + "detailedupdate desc", + "100"); + + return getFirstColumn(cursor); + } catch (final Exception e) { + Log.e("DataStore.allDetailedThere", e); + return new String[0]; + } + } + + public static boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { + init(); + + long dataUpdated = 0; + long dataDetailedUpdate = 0; + int dataDetailed = 0; + + try { + Cursor cursor; + + if (StringUtils.isNotBlank(geocode)) { + cursor = database.query( + dbTableCaches, + new String[]{"detailed", "detailedupdate", "updated"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + null, + "1"); + } else if (StringUtils.isNotBlank(guid)) { + cursor = database.query( + dbTableCaches, + new String[]{"detailed", "detailedupdate", "updated"}, + "guid = ?", + new String[]{guid}, + null, + null, + null, + "1"); + } else { + return false; + } + + if (cursor.moveToFirst()) { + dataDetailed = cursor.getInt(0); + dataDetailedUpdate = cursor.getLong(1); + dataUpdated = cursor.getLong(2); + } + + cursor.close(); + } catch (final Exception e) { + Log.e("DataStore.isThere", e); + } + + if (detailed && dataDetailed == 0) { + // we want details, but these are not stored + return false; + } + + if (checkTime && detailed && dataDetailedUpdate < (System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED)) { + // we want to check time for detailed cache, but data are older than 3 hours + return false; + } + + if (checkTime && !detailed && dataUpdated < (System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED)) { + // we want to check time for short cache, but data are older than 3 hours + return false; + } + + // we have some cache + return true; + } + + /** is cache stored in one of the lists (not only temporary) */ + public static boolean isOffline(String geocode, String guid) { + if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { + return false; + } + init(); + + try { + final SQLiteStatement listId; + final String value; + if (StringUtils.isNotBlank(geocode)) { + listId = PreparedStatements.getListIdOfGeocode(); + value = geocode; + } + else { + listId = PreparedStatements.getListIdOfGuid(); + value = guid; + } + synchronized (listId) { + listId.bindString(1, value); + return listId.simpleQueryForLong() != StoredList.TEMPORARY_LIST_ID; + } + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache + } catch (Exception e) { + Log.e("DataStore.isOffline", e); + } + + return false; + } + + public static String getGeocodeForGuid(String guid) { + if (StringUtils.isBlank(guid)) { + return null; + } + init(); + + try { + final SQLiteStatement description = PreparedStatements.getGeocodeOfGuid(); + synchronized (description) { + description.bindString(1, guid); + return description.simpleQueryForString(); + } + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache + } catch (Exception e) { + Log.e("DataStore.getGeocodeForGuid", e); + } + + return null; + } + + public static String getCacheidForGeocode(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + init(); + + try { + final SQLiteStatement description = PreparedStatements.getCacheIdOfGeocode(); + synchronized (description) { + description.bindString(1, geocode); + return description.simpleQueryForString(); + } + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache + } catch (Exception e) { + Log.e("DataStore.getCacheidForGeocode", e); + } + + return null; + } + + /** + * Save/store a cache to the CacheCache + * + * @param cache + * the Cache to save in the CacheCache/DB + * @param saveFlags + * + * @return true = cache saved successfully to the CacheCache/DB + */ + public static boolean saveCache(Geocache cache, EnumSet saveFlags) { + if (cache == null) { + throw new IllegalArgumentException("cache must not be null"); + } + + // Merge with the data already stored in the CacheCache or in the database if + // the cache had not been loaded before, and update the CacheCache. + // Also, a DB update is required if the merge data comes from the CacheCache + // (as it may be more recent than the version in the database), or if the + // version coming from the database is different than the version we are entering + // into the cache (that includes absence from the database). + final String geocode = cache.getGeocode(); + final Geocache cacheFromCache = cacheCache.getCacheFromCache(geocode); + final boolean dbUpdateRequired = + !cache.gatherMissingFrom(cacheFromCache != null ? + cacheFromCache : + loadCache(geocode, LoadFlags.LOAD_ALL_DB_ONLY)) || + cacheFromCache != null; + cache.addStorageLocation(StorageLocation.CACHE); + cacheCache.putCacheInCache(cache); + + // Only save the cache in the database if it is requested by the caller and + // the cache contains detailed information. + if (!saveFlags.contains(SaveFlag.SAVE_DB)) { + return true; + } + + return cache.isDetailed() && dbUpdateRequired && storeIntoDatabase(cache); + } + + private static boolean storeIntoDatabase(final Geocache cache) { + cache.addStorageLocation(StorageLocation.DATABASE); + cacheCache.putCacheInCache(cache); + Log.d("Saving " + cache.toString() + " (" + cache.getListId() + ") to DB"); + + ContentValues values = new ContentValues(); + + if (cache.getUpdated() == 0) { + values.put("updated", System.currentTimeMillis()); + } else { + values.put("updated", cache.getUpdated()); + } + values.put("reason", cache.getListId()); + values.put("detailed", cache.isDetailed() ? 1 : 0); + values.put("detailedupdate", cache.getDetailedUpdate()); + values.put("visiteddate", cache.getVisitedDate()); + values.put("geocode", cache.getGeocode()); + values.put("cacheid", cache.getCacheId()); + values.put("guid", cache.getGuid()); + values.put("type", cache.getType().id); + values.put("name", cache.getName()); + values.put("owner", cache.getOwnerDisplayName()); + values.put("owner_real", cache.getOwnerUserId()); + if (cache.getHiddenDate() == null) { + values.put("hidden", 0); + } else { + values.put("hidden", cache.getHiddenDate().getTime()); + } + values.put("hint", cache.getHint()); + values.put("size", cache.getSize() == null ? "" : cache.getSize().id); + values.put("difficulty", cache.getDifficulty()); + values.put("terrain", cache.getTerrain()); + values.put("location", cache.getLocation()); + values.put("distance", cache.getDistance()); + values.put("direction", cache.getDirection()); + putCoords(values, cache.getCoords()); + values.put("reliable_latlon", cache.isReliableLatLon() ? 1 : 0); + values.put("shortdesc", cache.getShortDescription()); + values.put("personal_note", cache.getPersonalNote()); + values.put("description", cache.getDescription()); + values.put("favourite_cnt", cache.getFavoritePoints()); + values.put("rating", cache.getRating()); + values.put("votes", cache.getVotes()); + values.put("myvote", cache.getMyVote()); + values.put("disabled", cache.isDisabled() ? 1 : 0); + values.put("archived", cache.isArchived() ? 1 : 0); + values.put("members", cache.isPremiumMembersOnly() ? 1 : 0); + values.put("found", cache.isFound() ? 1 : 0); + values.put("favourite", cache.isFavorite() ? 1 : 0); + values.put("inventoryunknown", cache.getInventoryItems()); + values.put("onWatchlist", cache.isOnWatchlist() ? 1 : 0); + values.put("coordsChanged", cache.hasUserModifiedCoords() ? 1 : 0); + values.put("finalDefined", cache.hasFinalDefined() ? 1 : 0); + values.put("logPasswordRequired", cache.isLogPasswordRequired() ? 1 : 0); + + init(); + + //try to update record else insert fresh.. + database.beginTransaction(); + + try { + saveAttributesWithoutTransaction(cache); + saveOriginalWaypointsWithoutTransaction(cache); + saveSpoilersWithoutTransaction(cache); + saveLogsWithoutTransaction(cache.getGeocode(), cache.getLogs()); + saveLogCountsWithoutTransaction(cache); + saveInventoryWithoutTransaction(cache.getGeocode(), cache.getInventory()); + + int rows = database.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() }); + if (rows == 0) { + // cache is not in the DB, insert it + /* long id = */ + database.insert(dbTableCaches, null, values); + } + database.setTransactionSuccessful(); + return true; + } catch (Exception e) { + Log.e("SaveCache", e); + } finally { + database.endTransaction(); + } + + return false; + } + + private static void saveAttributesWithoutTransaction(final Geocache cache) { + String geocode = cache.getGeocode(); + database.delete(dbTableAttributes, "geocode = ?", new String[]{geocode}); + + if (cache.getAttributes().isEmpty()) { + return; + } + SQLiteStatement statement = PreparedStatements.getInsertAttribute(); + final long timestamp = System.currentTimeMillis(); + for (String attribute : cache.getAttributes()) { + statement.bindString(1, geocode); + statement.bindLong(2, timestamp); + statement.bindString(3, attribute); + + statement.executeInsert(); + } + } + + /** + * Persists the given destination into the database. + * + * @param destination + * a destination to save + */ + public static void saveSearchedDestination(final Destination destination) { + init(); + + database.beginTransaction(); + + try { + SQLiteStatement insertDestination = PreparedStatements.getInsertSearchDestination(destination); + insertDestination.executeInsert(); + database.setTransactionSuccessful(); + } catch (Exception e) { + Log.e("Updating searchedDestinations db failed", e); + } finally { + database.endTransaction(); + } + } + + public static boolean saveWaypoints(final Geocache cache) { + init(); + database.beginTransaction(); + + try { + saveOriginalWaypointsWithoutTransaction(cache); + database.setTransactionSuccessful(); + return true; + } catch (Exception e) { + Log.e("saveWaypoints", e); + } finally { + database.endTransaction(); + } + return false; + } + + private static void saveOriginalWaypointsWithoutTransaction(final Geocache cache) { + String geocode = cache.getGeocode(); + + List waypoints = cache.getWaypoints(); + if (CollectionUtils.isNotEmpty(waypoints)) { + ContentValues values = new ContentValues(); + long timeStamp = System.currentTimeMillis(); + for (Waypoint oneWaypoint : waypoints) { + if (oneWaypoint.isUserDefined()) { + continue; + } + + values.clear(); + values.put("geocode", geocode); + values.put("updated", timeStamp); + values.put("type", oneWaypoint.getWaypointType() != null ? oneWaypoint.getWaypointType().id : null); + values.put("prefix", oneWaypoint.getPrefix()); + values.put("lookup", oneWaypoint.getLookup()); + values.put("name", oneWaypoint.getName()); + values.put("latlon", oneWaypoint.getLatlon()); + putCoords(values, oneWaypoint.getCoords()); + values.put("note", oneWaypoint.getNote()); + values.put("own", oneWaypoint.isUserDefined() ? 1 : 0); + values.put("visited", oneWaypoint.isVisited() ? 1 : 0); + if (oneWaypoint.getId() < 0) { + final long rowId = database.insert(dbTableWaypoints, null, values); + oneWaypoint.setId((int) rowId); + } else { + database.update(dbTableWaypoints, values, "_id = ?", new String[] { Integer.toString(oneWaypoint.getId(), 10) }); + } + } + } + } + + /** + * Save coordinates into a ContentValues + * + * @param values + * a ContentValues to save coordinates in + * @param oneWaypoint + * coordinates to save, or null to save empty coordinates + */ + private static void putCoords(final ContentValues values, final Geopoint coords) { + values.put("latitude", coords == null ? null : coords.getLatitude()); + values.put("longitude", coords == null ? null : coords.getLongitude()); + } + + /** + * Retrieve coordinates from a Cursor + * + * @param cursor + * a Cursor representing a row in the database + * @param indexLat + * index of the latitude column + * @param indexLon + * index of the longitude column + * @return the coordinates, or null if latitude or longitude is null or the coordinates are invalid + */ + private static Geopoint getCoords(final Cursor cursor, final int indexLat, final int indexLon) { + if (cursor.isNull(indexLat) || cursor.isNull(indexLon)) { + return null; + } + + return new Geopoint(cursor.getDouble(indexLat), cursor.getDouble(indexLon)); + } + + private static boolean saveWaypointInternal(int id, String geocode, Waypoint waypoint) { + if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { + return false; + } + + init(); + + database.beginTransaction(); + boolean ok = false; + try { + ContentValues values = new ContentValues(); + values.put("geocode", geocode); + values.put("updated", System.currentTimeMillis()); + values.put("type", waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null); + values.put("prefix", waypoint.getPrefix()); + values.put("lookup", waypoint.getLookup()); + values.put("name", waypoint.getName()); + values.put("latlon", waypoint.getLatlon()); + putCoords(values, waypoint.getCoords()); + values.put("note", waypoint.getNote()); + values.put("own", waypoint.isUserDefined() ? 1 : 0); + values.put("visited", waypoint.isVisited() ? 1 : 0); + if (id <= 0) { + final long rowId = database.insert(dbTableWaypoints, null, values); + waypoint.setId((int) rowId); + ok = true; + } else { + final int rows = database.update(dbTableWaypoints, values, "_id = " + id, null); + ok = rows > 0; + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + + return ok; + } + + public static boolean deleteWaypoint(int id) { + if (id == 0) { + return false; + } + + init(); + + return database.delete(dbTableWaypoints, "_id = " + id, null) > 0; + } + + private static void saveSpoilersWithoutTransaction(final Geocache cache) { + String geocode = cache.getGeocode(); + database.delete(dbTableSpoilers, "geocode = ?", new String[]{geocode}); + + List spoilers = cache.getSpoilers(); + if (CollectionUtils.isNotEmpty(spoilers)) { + SQLiteStatement insertSpoiler = PreparedStatements.getInsertSpoiler(); + final long timestamp = System.currentTimeMillis(); + for (Image spoiler : spoilers) { + insertSpoiler.bindString(1, geocode); + insertSpoiler.bindLong(2, timestamp); + insertSpoiler.bindString(3, spoiler.getUrl()); + insertSpoiler.bindString(4, spoiler.getTitle()); + final String description = spoiler.getDescription(); + if (description != null) { + insertSpoiler.bindString(5, description); + } + else { + insertSpoiler.bindNull(5); + } + insertSpoiler.executeInsert(); + } + } + } + + private static void saveLogsWithoutTransaction(final String geocode, final Iterable logs) { + // TODO delete logimages referring these logs + database.delete(dbTableLogs, "geocode = ?", new String[]{geocode}); + + if (!logs.iterator().hasNext()) { + return; + } + + SQLiteStatement insertLog = PreparedStatements.getInsertLog(); + final long timestamp = System.currentTimeMillis(); + for (LogEntry log : logs) { + insertLog.bindString(1, geocode); + insertLog.bindLong(2, timestamp); + insertLog.bindLong(3, log.type.id); + insertLog.bindString(4, log.author); + insertLog.bindString(5, log.log); + insertLog.bindLong(6, log.date); + insertLog.bindLong(7, log.found); + insertLog.bindLong(8, log.friend ? 1 : 0); + long logId = insertLog.executeInsert(); + if (log.hasLogImages()) { + SQLiteStatement insertImage = PreparedStatements.getInsertLogImage(); + for (Image img : log.getLogImages()) { + insertImage.bindLong(1, logId); + insertImage.bindString(2, img.getTitle()); + insertImage.bindString(3, img.getUrl()); + insertImage.executeInsert(); + } + } + } + } + + private static void saveLogCountsWithoutTransaction(final Geocache cache) { + String geocode = cache.getGeocode(); + database.delete(dbTableLogCount, "geocode = ?", new String[]{geocode}); + + Map logCounts = cache.getLogCounts(); + if (MapUtils.isNotEmpty(logCounts)) { + Set> logCountsItems = logCounts.entrySet(); + SQLiteStatement insertLogCounts = PreparedStatements.getInsertLogCounts(); + final long timestamp = System.currentTimeMillis(); + for (Entry pair : logCountsItems) { + insertLogCounts.bindString(1, geocode); + insertLogCounts.bindLong(2, timestamp); + insertLogCounts.bindLong(3, pair.getKey().id); + insertLogCounts.bindLong(4, pair.getValue()); + + insertLogCounts.executeInsert(); + } + } + } + + public static void saveTrackable(final Trackable trackable) { + init(); + + database.beginTransaction(); + try { + saveInventoryWithoutTransaction(null, Collections.singletonList(trackable)); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + private static void saveInventoryWithoutTransaction(final String geocode, final List trackables) { + if (geocode != null) { + database.delete(dbTableTrackables, "geocode = ?", new String[]{geocode}); + } + + if (CollectionUtils.isNotEmpty(trackables)) { + ContentValues values = new ContentValues(); + long timeStamp = System.currentTimeMillis(); + for (Trackable trackable : trackables) { + final String tbCode = trackable.getGeocode(); + if (StringUtils.isNotBlank(tbCode)) { + database.delete(dbTableTrackables, "tbcode = ?", new String[] { tbCode }); + } + values.clear(); + if (geocode != null) { + values.put("geocode", geocode); + } + values.put("updated", timeStamp); + values.put("tbcode", tbCode); + values.put("guid", trackable.getGuid()); + values.put("title", trackable.getName()); + values.put("owner", trackable.getOwner()); + if (trackable.getReleased() != null) { + values.put("released", trackable.getReleased().getTime()); + } else { + values.put("released", 0L); + } + values.put("goal", trackable.getGoal()); + values.put("description", trackable.getDetails()); + + database.insert(dbTableTrackables, null, values); + + saveLogsWithoutTransaction(tbCode, trackable.getLogs()); + } + } + } + + public static Viewport getBounds(final Set geocodes) { + if (CollectionUtils.isEmpty(geocodes)) { + return null; + } + + final Set caches = loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); + return Viewport.containing(caches); + } + + /** + * Load a single Cache. + * + * @param geocode + * The Geocode GCXXXX + * @return the loaded cache (if found). Can be null + */ + public static Geocache loadCache(final String geocode, final EnumSet loadFlags) { + if (StringUtils.isBlank(geocode)) { + throw new IllegalArgumentException("geocode must not be empty"); + } + + final Set caches = loadCaches(Collections.singleton(geocode), loadFlags); + return caches.isEmpty() ? null : caches.iterator().next(); + } + + /** + * Load caches. + * + * @param geocodes + * @return Set of loaded caches. Never null. + */ + public static Set loadCaches(final Collection geocodes, final EnumSet loadFlags) { + if (CollectionUtils.isEmpty(geocodes)) { + return new HashSet(); + } + + Set result = new HashSet(); + Set remaining = new HashSet(geocodes); + + if (loadFlags.contains(LoadFlag.LOAD_CACHE_BEFORE)) { + for (String geocode : new HashSet(remaining)) { + Geocache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + result.add(cache); + remaining.remove(cache.getGeocode()); + } + } + } + + if (loadFlags.contains(LoadFlag.LOAD_DB_MINIMAL) || + loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES) || + loadFlags.contains(LoadFlag.LOAD_WAYPOINTS) || + loadFlags.contains(LoadFlag.LOAD_SPOILERS) || + loadFlags.contains(LoadFlag.LOAD_LOGS) || + loadFlags.contains(LoadFlag.LOAD_INVENTORY) || + loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { + + final Set cachesFromDB = loadCachesFromGeocodes(remaining, loadFlags); + result.addAll(cachesFromDB); + for (final Geocache cache : cachesFromDB) { + remaining.remove(cache.getGeocode()); + } + } + + if (loadFlags.contains(LoadFlag.LOAD_CACHE_AFTER)) { + for (String geocode : new HashSet(remaining)) { + Geocache cache = cacheCache.getCacheFromCache(geocode); + if (cache != null) { + result.add(cache); + remaining.remove(cache.getGeocode()); + } + } + } + + if (remaining.size() >= 1) { + Log.d("DataStore.loadCaches(" + remaining.toString() + ") returned no results"); + } + return result; + } + + /** + * Load caches. + * + * @param geocodes + * @param loadFlags + * @return Set of loaded caches. Never null. + */ + private static Set loadCachesFromGeocodes(final Set geocodes, final EnumSet loadFlags) { + if (CollectionUtils.isEmpty(geocodes)) { + return Collections.emptySet(); + } + + // do not log the entire collection of geo codes to the debug log. This can be more than 100 KB of text for large lists! + init(); + + final StringBuilder query = new StringBuilder(QUERY_CACHE_DATA); + if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { + query.append(',').append(dbTableLogsOffline).append(".log"); + } + + query.append(" FROM ").append(dbTableCaches); + if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { + query.append(" LEFT OUTER JOIN ").append(dbTableLogsOffline).append(" ON ( ").append(dbTableCaches).append(".geocode == ").append(dbTableLogsOffline).append(".geocode) "); + } + + query.append(" WHERE ").append(dbTableCaches).append('.'); + query.append(DataStore.whereGeocodeIn(geocodes)); + + Cursor cursor = database.rawQuery(query.toString(), null); + try { + final Set caches = new HashSet(); + int logIndex = -1; + + while (cursor.moveToNext()) { + Geocache cache = DataStore.createCacheFromDatabaseContent(cursor); + + if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) { + cache.setAttributes(loadAttributes(cache.getGeocode())); + } + + if (loadFlags.contains(LoadFlag.LOAD_WAYPOINTS)) { + final List waypoints = loadWaypoints(cache.getGeocode()); + if (CollectionUtils.isNotEmpty(waypoints)) { + cache.setWaypoints(waypoints, false); + } + } + + if (loadFlags.contains(LoadFlag.LOAD_SPOILERS)) { + final List spoilers = loadSpoilers(cache.getGeocode()); + cache.setSpoilers(spoilers); + } + + if (loadFlags.contains(LoadFlag.LOAD_LOGS)) { + cache.setLogs(loadLogs(cache.getGeocode())); + final Map logCounts = loadLogCounts(cache.getGeocode()); + if (MapUtils.isNotEmpty(logCounts)) { + cache.getLogCounts().clear(); + cache.getLogCounts().putAll(logCounts); + } + } + + if (loadFlags.contains(LoadFlag.LOAD_INVENTORY)) { + final List inventory = loadInventory(cache.getGeocode()); + if (CollectionUtils.isNotEmpty(inventory)) { + if (cache.getInventory() == null) { + cache.setInventory(new ArrayList()); + } else { + cache.getInventory().clear(); + } + cache.getInventory().addAll(inventory); + } + } + + if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { + if (logIndex < 0) { + logIndex = cursor.getColumnIndex("log"); + } + cache.setLogOffline(!cursor.isNull(logIndex)); + } + cache.addStorageLocation(StorageLocation.DATABASE); + cacheCache.putCacheInCache(cache); + + caches.add(cache); + } + return caches; + } finally { + cursor.close(); + } + } + + + /** + * Builds a where for a viewport with the size enhanced by 50%. + * + * @param dbTable + * @param viewport + * @return + */ + + private static String buildCoordinateWhere(final String dbTable, final Viewport viewport) { + return viewport.resize(1.5).sqlWhere(dbTable); + } + + /** + * creates a Cache from the cursor. Doesn't next. + * + * @param cursor + * @return Cache from DB + */ + private static Geocache createCacheFromDatabaseContent(Cursor cursor) { + Geocache cache = new Geocache(); + + cache.setUpdated(cursor.getLong(0)); + cache.setListId(cursor.getInt(1)); + cache.setDetailed(cursor.getInt(2) == 1); + cache.setDetailedUpdate(cursor.getLong(3)); + cache.setVisitedDate(cursor.getLong(4)); + cache.setGeocode(cursor.getString(5)); + cache.setCacheId(cursor.getString(6)); + cache.setGuid(cursor.getString(7)); + cache.setType(CacheType.getById(cursor.getString(8))); + cache.setName(cursor.getString(9)); + cache.setOwnerDisplayName(cursor.getString(10)); + cache.setOwnerUserId(cursor.getString(11)); + long dateValue = cursor.getLong(12); + if (dateValue != 0) { + cache.setHidden(new Date(dateValue)); + } + // do not set cache.hint + cache.setSize(CacheSize.getById(cursor.getString(14))); + cache.setDifficulty(cursor.getFloat(15)); + int index = 16; + if (cursor.isNull(index)) { + cache.setDirection(null); + } else { + cache.setDirection(cursor.getFloat(index)); + } + index = 17; + if (cursor.isNull(index)) { + cache.setDistance(null); + } else { + cache.setDistance(cursor.getFloat(index)); + } + cache.setTerrain(cursor.getFloat(18)); + // do not set cache.location + cache.setCoords(getCoords(cursor, 36, 37)); + cache.setPersonalNote(cursor.getString(21)); + // do not set cache.shortdesc + // do not set cache.description + cache.setFavoritePoints(cursor.getInt(23)); + cache.setRating(cursor.getFloat(24)); + cache.setVotes(cursor.getInt(25)); + cache.setMyVote(cursor.getFloat(26)); + cache.setDisabled(cursor.getInt(27) == 1); + cache.setArchived(cursor.getInt(28) == 1); + cache.setPremiumMembersOnly(cursor.getInt(29) == 1); + cache.setFound(cursor.getInt(30) == 1); + cache.setFavorite(cursor.getInt(31) == 1); + cache.setInventoryItems(cursor.getInt(32)); + cache.setOnWatchlist(cursor.getInt(33) == 1); + cache.setReliableLatLon(cursor.getInt(34) > 0); + cache.setUserModifiedCoords(cursor.getInt(35) > 0); + cache.setFinalDefined(cursor.getInt(38) > 0); + cache.setLogPasswordRequired(cursor.getInt(42) > 0); + + Log.d("Loading " + cache.toString() + " (" + cache.getListId() + ") from DB"); + + return cache; + } + + public static List loadAttributes(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final ArrayList attributes = new ArrayList(); + + final Cursor cursor = database.query( + dbTableAttributes, + new String[]{"attribute"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + null, + "100"); + + while (cursor.moveToNext()) { + attributes.add(cursor.getString(0)); + } + + cursor.close(); + + return attributes; + } + + public static Waypoint loadWaypoint(int id) { + if (id == 0) { + return null; + } + + init(); + + final Cursor cursor = database.query( + dbTableWaypoints, + WAYPOINT_COLUMNS, + "_id = ?", + new String[]{Integer.toString(id)}, + null, + null, + null, + "1"); + + Log.d("DataStore.loadWaypoint(" + id + ")"); + + final Waypoint waypoint = cursor.moveToFirst() ? createWaypointFromDatabaseContent(cursor) : null; + + cursor.close(); + + return waypoint; + } + + public static List loadWaypoints(final String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final List waypoints = new ArrayList(); + + final Cursor cursor = database.query( + dbTableWaypoints, + WAYPOINT_COLUMNS, + "geocode = ?", + new String[]{geocode}, + null, + null, + "_id", + "100"); + + while (cursor.moveToNext()) { + waypoints.add(createWaypointFromDatabaseContent(cursor)); + } + + cursor.close(); + + return waypoints; + } + + private static Waypoint createWaypointFromDatabaseContent(final Cursor cursor) { + final String name = cursor.getString(cursor.getColumnIndex("name")); + final WaypointType type = WaypointType.findById(cursor.getString(cursor.getColumnIndex("type"))); + final boolean own = cursor.getInt(cursor.getColumnIndex("own")) != 0; + final Waypoint waypoint = new Waypoint(name, type, own); + waypoint.setVisited(cursor.getInt(cursor.getColumnIndex("visited")) != 0); + waypoint.setId(cursor.getInt(cursor.getColumnIndex("_id"))); + waypoint.setGeocode(cursor.getString(cursor.getColumnIndex("geocode"))); + waypoint.setPrefix(cursor.getString(cursor.getColumnIndex("prefix"))); + waypoint.setLookup(cursor.getString(cursor.getColumnIndex("lookup"))); + waypoint.setLatlon(cursor.getString(cursor.getColumnIndex("latlon"))); + waypoint.setCoords(getCoords(cursor, cursor.getColumnIndex("latitude"), cursor.getColumnIndex("longitude"))); + waypoint.setNote(cursor.getString(cursor.getColumnIndex("note"))); + + return waypoint; + } + + private static List loadSpoilers(final String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final List spoilers = new ArrayList(); + + final Cursor cursor = database.query( + dbTableSpoilers, + new String[]{"url", "title", "description"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + null, + "100"); + + while (cursor.moveToNext()) { + spoilers.add(new Image(cursor.getString(0), cursor.getString(1), cursor.getString(2))); + } + + cursor.close(); + + return spoilers; + } + + /** + * Loads the history of previously entered destinations from + * the database. If no destinations exist, an {@link Collections#emptyList()} will be returned. + * + * @return A list of previously entered destinations or an empty list. + */ + public static List loadHistoryOfSearchedLocations() { + init(); + + final Cursor cursor = database.query(dbTableSearchDestionationHistory, + new String[]{"_id", "date", "latitude", "longitude"}, + null, + null, + null, + null, + "date desc", + "100"); + + final List destinations = new LinkedList(); + + while (cursor.moveToNext()) { + final Destination dest = new Destination(cursor.getLong(0), cursor.getLong(1), getCoords(cursor, 2, 3)); + + // If coordinates are non-existent or invalid, do not consider this point. + if (dest.getCoords() != null) { + destinations.add(dest); + } + } + + cursor.close(); + + return destinations; + } + + public static boolean clearSearchedDestinations() { + init(); + database.beginTransaction(); + + try { + database.delete(dbTableSearchDestionationHistory, null, null); + database.setTransactionSuccessful(); + return true; + } catch (Exception e) { + Log.e("Unable to clear searched destinations", e); + } finally { + database.endTransaction(); + } + + return false; + } + + public static List loadLogs(String geocode) { + List logs = new ArrayList(); + + if (StringUtils.isBlank(geocode)) { + return logs; + } + + init(); + + final Cursor cursor = database.rawQuery( + /* 0 1 2 3 4 5 6 7 8 9 10 */ + "SELECT cg_logs._id as cg_logs_id, type, author, log, date, found, friend, " + dbTableLogImages + "._id as cg_logImages_id, log_id, title, url" + + " FROM " + dbTableLogs + " LEFT OUTER JOIN " + dbTableLogImages + + " ON ( cg_logs._id = log_id ) WHERE geocode = ? ORDER BY date desc, cg_logs._id asc", new String[]{geocode}); + + LogEntry log = null; + while (cursor.moveToNext() && logs.size() < 100) { + if (log == null || log.id != cursor.getInt(0)) { + log = new LogEntry( + cursor.getString(2), + cursor.getLong(4), + LogType.getById(cursor.getInt(1)), + cursor.getString(3)); + log.id = cursor.getInt(0); + log.found = cursor.getInt(5); + log.friend = cursor.getInt(6) == 1; + logs.add(log); + } + if (!cursor.isNull(7)) { + log.addLogImage(new Image(cursor.getString(10), cursor.getString(9))); + } + } + + cursor.close(); + + return logs; + } + + public static Map loadLogCounts(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final Map logCounts = new HashMap(); + + final Cursor cursor = database.query( + dbTableLogCount, + new String[]{"type", "count"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + null, + "100"); + + while (cursor.moveToNext()) { + logCounts.put(LogType.getById(cursor.getInt(0)), cursor.getInt(1)); + } + + cursor.close(); + + return logCounts; + } + + private static List loadInventory(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final List trackables = new ArrayList(); + + final Cursor cursor = database.query( + dbTableTrackables, + new String[]{"_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + "title COLLATE NOCASE ASC", + "100"); + + while (cursor.moveToNext()) { + trackables.add(createTrackableFromDatabaseContent(cursor)); + } + + cursor.close(); + + return trackables; + } + + public static Trackable loadTrackable(final String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + final Cursor cursor = database.query( + dbTableTrackables, + new String[]{"updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, + "tbcode = ?", + new String[]{geocode}, + null, + null, + null, + "1"); + + final Trackable trackable = cursor.moveToFirst() ? createTrackableFromDatabaseContent(cursor) : null; + + cursor.close(); + + return trackable; + } + + private static Trackable createTrackableFromDatabaseContent(final Cursor cursor) { + final Trackable trackable = new Trackable(); + trackable.setGeocode(cursor.getString(cursor.getColumnIndex("tbcode"))); + trackable.setGuid(cursor.getString(cursor.getColumnIndex("guid"))); + trackable.setName(cursor.getString(cursor.getColumnIndex("title"))); + trackable.setOwner(cursor.getString(cursor.getColumnIndex("owner"))); + final String released = cursor.getString(cursor.getColumnIndex("released")); + if (released != null) { + try { + long releaseMilliSeconds = Long.parseLong(released); + trackable.setReleased(new Date(releaseMilliSeconds)); + } catch (final NumberFormatException e) { + Log.e("createTrackableFromDatabaseContent", e); + } + } + trackable.setGoal(cursor.getString(cursor.getColumnIndex("goal"))); + trackable.setDetails(cursor.getString(cursor.getColumnIndex("description"))); + trackable.setLogs(loadLogs(trackable.getGeocode())); + return trackable; + } + + /** + * Number of caches stored for a given type and/or list + * + * @param cacheType + * @param list + * @return + */ + public static int getAllStoredCachesCount(final CacheType cacheType, final int list) { + if (cacheType == null) { + throw new IllegalArgumentException("cacheType must not be null"); + } + if (list <= 0) { + throw new IllegalArgumentException("list must be > 0"); + } + init(); + + try { + StringBuilder sql = new StringBuilder("select count(_id) from " + dbTableCaches + " where detailed = 1"); + String typeKey; + int reasonIndex; + if (cacheType != CacheType.ALL) { + sql.append(" and type = ?"); + typeKey = cacheType.id; + reasonIndex = 2; + } + else { + typeKey = "all_types"; + reasonIndex = 1; + } + String listKey; + if (list == StoredList.ALL_LIST_ID) { + sql.append(" and reason > 0"); + listKey = "all_list"; + } else { + sql.append(" and reason = ?"); + listKey = "list"; + } + + String key = "CountCaches_" + typeKey + "_" + listKey; + + SQLiteStatement compiledStmnt = PreparedStatements.getStatement(key, sql.toString()); + if (cacheType != CacheType.ALL) { + compiledStmnt.bindString(1, cacheType.id); + } + if (list != StoredList.ALL_LIST_ID) { + compiledStmnt.bindLong(reasonIndex, list); + } + return (int) compiledStmnt.simpleQueryForLong(); + } catch (Exception e) { + Log.e("DataStore.loadAllStoredCachesCount", e); + } + + return 0; + } + + public static int getAllHistoryCachesCount() { + init(); + + try { + return (int) PreparedStatements.getCountHistoryCaches().simpleQueryForLong(); + } catch (Exception e) { + Log.e("DataStore.getAllHistoricCachesCount", e); + } + + return 0; + } + + /** + * Return a batch of stored geocodes. + * + * @param coords + * the current coordinates to sort by distance, or null to sort by geocode + * @param cacheType + * @param listId + * @return a non-null set of geocodes + */ + private static Set loadBatchOfStoredGeocodes(final Geopoint coords, final CacheType cacheType, final int listId) { + if (cacheType == null) { + throw new IllegalArgumentException("cacheType must not be null"); + } + init(); + + final Set geocodes = new HashSet(); + + final StringBuilder selection = new StringBuilder(); + + selection.append("reason "); + selection.append(listId != StoredList.ALL_LIST_ID ? "=" + Math.max(listId, 1) : ">= " + StoredList.STANDARD_LIST_ID); + selection.append(" and detailed = 1 "); + + String[] selectionArgs = null; + if (cacheType != CacheType.ALL) { + selection.append(" and type = ?"); + selectionArgs = new String[] { String.valueOf(cacheType.id) }; + } + + try { + Cursor cursor; + if (coords != null) { + cursor = database.query( + dbTableCaches, + new String[]{"geocode", "(abs(latitude-" + String.format((Locale) null, "%.6f", coords.getLatitude()) + + ") + abs(longitude-" + String.format((Locale) null, "%.6f", coords.getLongitude()) + ")) as dif"}, + selection.toString(), + selectionArgs, + null, + null, + "dif", + null); + } else { + cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + selection.toString(), + selectionArgs, + null, + null, + "geocode"); + } + + while (cursor.moveToNext()) { + geocodes.add(cursor.getString(0)); + } + + cursor.close(); + } catch (final Exception e) { + Log.e("DataStore.loadBatchOfStoredGeocodes", e); + } + + return geocodes; + } + + private static Set loadBatchOfHistoricGeocodes(final boolean detailedOnly, final CacheType cacheType) { + init(); + + final Set geocodes = new HashSet(); + + final StringBuilder selection = new StringBuilder("visiteddate > 0"); + + if (detailedOnly) { + selection.append(" and detailed = 1"); + } + String[] selectionArgs = null; + if (cacheType != CacheType.ALL) { + selection.append(" and type = ?"); + selectionArgs = new String[] { String.valueOf(cacheType.id) }; + } + + try { + final Cursor cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + selection.toString(), + selectionArgs, + null, + null, + "visiteddate", + null); + while (cursor.moveToNext()) { + geocodes.add(cursor.getString(0)); + } + cursor.close(); + } catch (Exception e) { + Log.e("DataStore.loadBatchOfHistoricGeocodes", e); + } + + return geocodes; + } + + /** Retrieve all stored caches from DB */ + public static SearchResult loadCachedInViewport(final Viewport viewport, final CacheType cacheType) { + return loadInViewport(false, viewport, cacheType); + } + + /** Retrieve stored caches from DB with listId >= 1 */ + public static SearchResult loadStoredInViewport(final Viewport viewport, final CacheType cacheType) { + return loadInViewport(true, viewport, cacheType); + } + + /** + * Loads the geocodes of caches in a viewport from CacheCache and/or Database + * + * @param stored + * True - query only stored caches, False - query cached ones as well + * @param centerLat + * @param centerLon + * @param spanLat + * @param spanLon + * @param cacheType + * @return Set with geocodes + */ + private static SearchResult loadInViewport(final boolean stored, final Viewport viewport, final CacheType cacheType) { + init(); + + final Set geocodes = new HashSet(); + + // if not stored only, get codes from CacheCache as well + if (!stored) { + geocodes.addAll(cacheCache.getInViewport(viewport, cacheType)); + } + + // viewport limitation + final StringBuilder selection = new StringBuilder(buildCoordinateWhere(dbTableCaches, viewport)); + + // cacheType limitation + String[] selectionArgs = null; + if (cacheType != CacheType.ALL) { + selection.append(" and type = ?"); + selectionArgs = new String[] { String.valueOf(cacheType.id) }; + } + + // offline caches only + if (stored) { + selection.append(" and reason >= " + StoredList.STANDARD_LIST_ID); + } + + try { + final Cursor cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + selection.toString(), + selectionArgs, + null, + null, + null, + "500"); + + while (cursor.moveToNext()) { + geocodes.add(cursor.getString(0)); + } + + cursor.close(); + } catch (final Exception e) { + Log.e("DataStore.loadInViewport", e); + } + + return new SearchResult(geocodes); + } + + /** delete caches from the DB store 3 days or more before */ + public static void clean() { + clean(false); + } + + /** + * Remove caches with listId = 0 + * + * @param more + * true = all caches false = caches stored 3 days or more before + */ + public static void clean(final boolean more) { + if (databaseCleaned) { + return; + } + + init(); + + Log.d("Database clean: started"); + + try { + Cursor cursor; + if (more) { + cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + "reason = 0", + null, + null, + null, + null, + null); + } else { + long timestamp = System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED; + String timestampString = Long.toString(timestamp); + cursor = database.query( + dbTableCaches, + new String[]{"geocode"}, + "reason = 0 and detailed < ? and detailedupdate < ? and visiteddate < ?", + new String[]{timestampString, timestampString, timestampString}, + null, + null, + null, + null); + } + + Set geocodes = new HashSet(); + while (cursor.moveToNext()) { + geocodes.add(cursor.getString(0)); + } + + cursor.close(); + + if (!geocodes.isEmpty()) { + Log.d("Database clean: removing " + geocodes.size() + " geocaches from listId=0"); + removeCaches(geocodes, LoadFlags.REMOVE_ALL); + } + } catch (final Exception e) { + Log.w("DataStore.clean", e); + } + + Log.d("Database clean: finished"); + databaseCleaned = true; + } + + public static void removeAllFromCache() { + // clean up CacheCache + cacheCache.removeAllFromCache(); + } + + public static void removeCache(final String geocode, EnumSet removeFlags) { + removeCaches(Collections.singleton(geocode), removeFlags); + } + + /** + * Drop caches from the tables they are stored into, as well as the cache files + * + * @param geocodes + * list of geocodes to drop from cache + */ + public static void removeCaches(final Set geocodes, EnumSet removeFlags) { + if (CollectionUtils.isEmpty(geocodes)) { + return; + } + + init(); + + if (removeFlags.contains(RemoveFlag.REMOVE_CACHE)) { + for (final String geocode : geocodes) { + cacheCache.removeCacheFromCache(geocode); + } + } + + if (removeFlags.contains(RemoveFlag.REMOVE_DB)) { + // Drop caches from the database + final ArrayList quotedGeocodes = new ArrayList(geocodes.size()); + for (final String geocode : geocodes) { + quotedGeocodes.add(DatabaseUtils.sqlEscapeString(geocode)); + } + final String geocodeList = StringUtils.join(quotedGeocodes.toArray(), ','); + final String baseWhereClause = "geocode in (" + geocodeList + ")"; + database.beginTransaction(); + try { + database.delete(dbTableCaches, baseWhereClause, null); + database.delete(dbTableAttributes, baseWhereClause, null); + database.delete(dbTableSpoilers, baseWhereClause, null); + database.delete(dbTableLogs, baseWhereClause, null); + database.delete(dbTableLogCount, baseWhereClause, null); + database.delete(dbTableLogsOffline, baseWhereClause, null); + String wayPointClause = baseWhereClause; + if (!removeFlags.contains(RemoveFlag.REMOVE_OWN_WAYPOINTS_ONLY_FOR_TESTING)) { + wayPointClause += " and type <> 'own'"; + } + database.delete(dbTableWaypoints, wayPointClause, null); + database.delete(dbTableTrackables, baseWhereClause, null); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + + // Delete cache directories + for (final String geocode : geocodes) { + LocalStorage.deleteDirectory(LocalStorage.getStorageDir(geocode)); + } + } + } + + public static boolean saveLogOffline(String geocode, Date date, LogType type, String log) { + if (StringUtils.isBlank(geocode)) { + Log.e("DataStore.saveLogOffline: cannot log a blank geocode"); + return false; + } + if (LogType.UNKNOWN == type && StringUtils.isBlank(log)) { + Log.e("DataStore.saveLogOffline: cannot log an unknown log type and no message"); + return false; + } + + init(); + + final ContentValues values = new ContentValues(); + values.put("geocode", geocode); + values.put("updated", System.currentTimeMillis()); + values.put("type", type.id); + values.put("log", log); + values.put("date", date.getTime()); + + if (hasLogOffline(geocode)) { + final int rows = database.update(dbTableLogsOffline, values, "geocode = ?", new String[] { geocode }); + return rows > 0; + } + final long id = database.insert(dbTableLogsOffline, null, values); + return id != -1; + } + + public static LogEntry loadLogOffline(String geocode) { + if (StringUtils.isBlank(geocode)) { + return null; + } + + init(); + + + final Cursor cursor = database.query( + dbTableLogsOffline, + new String[]{"_id", "type", "log", "date"}, + "geocode = ?", + new String[]{geocode}, + null, + null, + "_id desc", + "1"); + + LogEntry log = null; + if (cursor.moveToFirst()) { + log = new LogEntry(cursor.getLong(3), + LogType.getById(cursor.getInt(1)), + cursor.getString(2)); + log.id = cursor.getInt(0); + } + + cursor.close(); + + return log; + } + + public static void clearLogOffline(String geocode) { + if (StringUtils.isBlank(geocode)) { + return; + } + + init(); + + database.delete(dbTableLogsOffline, "geocode = ?", new String[]{geocode}); + } + + public static void clearLogsOffline(List caches) { + if (CollectionUtils.isEmpty(caches)) { + return; + } + + init(); + + Set geocodes = new HashSet(caches.size()); + for (Geocache cache : caches) { + geocodes.add(cache.getGeocode()); + cache.setLogOffline(false); + } + + database.execSQL(String.format("DELETE FROM %s where %s", dbTableLogsOffline, whereGeocodeIn(geocodes))); + } + + public static boolean hasLogOffline(final String geocode) { + if (StringUtils.isBlank(geocode)) { + return false; + } + + init(); + try { + final SQLiteStatement logCount = PreparedStatements.getLogCountOfGeocode(); + synchronized (logCount) { + logCount.bindString(1, geocode); + return logCount.simpleQueryForLong() > 0; + } + } catch (Exception e) { + Log.e("DataStore.hasLogOffline", e); + } + + return false; + } + + private static void setVisitDate(List geocodes, long visitedDate) { + if (geocodes.isEmpty()) { + return; + } + + init(); + + database.beginTransaction(); + try { + SQLiteStatement setVisit = PreparedStatements.getUpdateVisitDate(); + + for (String geocode : geocodes) { + setVisit.bindLong(1, visitedDate); + setVisit.bindString(2, geocode); + setVisit.execute(); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + @NonNull + public static List getLists() { + init(); + + final Resources res = cgeoapplication.getInstance().getResources(); + final List lists = new ArrayList(); + lists.add(new StoredList(StoredList.STANDARD_LIST_ID, res.getString(R.string.list_inbox), (int) PreparedStatements.getCountCachesOnStandardList().simpleQueryForLong())); + + try { + String query = "SELECT l._id as _id, l.title as title, COUNT(c._id) as count" + + " FROM " + dbTableLists + " l LEFT OUTER JOIN " + dbTableCaches + " c" + + " ON l._id + " + customListIdOffset + " = c.reason" + + " GROUP BY l._id" + + " ORDER BY l.title COLLATE NOCASE ASC"; + + final Cursor cursor = database.rawQuery(query, null); + ArrayList storedLists = getListsFromCursor(cursor); + lists.addAll(storedLists); + cursor.close(); + } catch (final Exception e) { + Log.e("DataStore.readLists", e); + } + return lists; + } + + private static ArrayList getListsFromCursor(final Cursor cursor) { + final int indexId = cursor.getColumnIndex("_id"); + final int indexTitle = cursor.getColumnIndex("title"); + final int indexCount = cursor.getColumnIndex("count"); + final ArrayList result = new ArrayList(); + while (cursor.moveToNext()) { + final int count = indexCount != -1 ? cursor.getInt(indexCount) : 0; + final StoredList list = new StoredList(cursor.getInt(indexId) + customListIdOffset, cursor.getString(indexTitle), count); + result.add(list); + } + cursor.close(); + return result; + } + + public static StoredList getList(int id) { + init(); + if (id >= customListIdOffset) { + Cursor cursor = database.query( + dbTableLists, + new String[]{"_id", "title"}, + "_id = ? ", + new String[] { String.valueOf(id - customListIdOffset) }, + null, + null, + null); + ArrayList lists = getListsFromCursor(cursor); + if (!lists.isEmpty()) { + return lists.get(0); + } + } + + Resources res = cgeoapplication.getInstance().getResources(); + if (id == StoredList.ALL_LIST_ID) { + return new StoredList(StoredList.ALL_LIST_ID, res.getString(R.string.list_all_lists), getAllCachesCount()); + } + + // fall back to standard list in case of invalid list id + if (id == StoredList.STANDARD_LIST_ID || id >= customListIdOffset) { + return new StoredList(StoredList.STANDARD_LIST_ID, res.getString(R.string.list_inbox), (int) PreparedStatements.getCountCachesOnStandardList().simpleQueryForLong()); + } + + return null; + } + + public static int getAllCachesCount() { + return (int) PreparedStatements.getCountAllCaches().simpleQueryForLong(); + } + + /** + * Create a new list + * + * @param name + * Name + * @return new listId + */ + public static int createList(String name) { + int id = -1; + if (StringUtils.isBlank(name)) { + return id; + } + + init(); + + database.beginTransaction(); + try { + ContentValues values = new ContentValues(); + values.put("title", name); + values.put("updated", System.currentTimeMillis()); + + id = (int) database.insert(dbTableLists, null, values); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + + return id >= 0 ? id + customListIdOffset : -1; + } + + /** + * @param listId + * List to change + * @param name + * New name of list + * @return Number of lists changed + */ + public static int renameList(final int listId, final String name) { + if (StringUtils.isBlank(name) || StoredList.STANDARD_LIST_ID == listId) { + return 0; + } + + init(); + + database.beginTransaction(); + int count = 0; + try { + ContentValues values = new ContentValues(); + values.put("title", name); + values.put("updated", System.currentTimeMillis()); + + count = database.update(dbTableLists, values, "_id = " + (listId - customListIdOffset), null); + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + + return count; + } + + /** + * Remove a list. Caches in the list are moved to the standard list. + * + * @param listId + * @return true if the list got deleted, false else + */ + public static boolean removeList(int listId) { + if (listId < customListIdOffset) { + return false; + } + + init(); + + database.beginTransaction(); + boolean status = false; + try { + int cnt = database.delete(dbTableLists, "_id = " + (listId - customListIdOffset), null); + + if (cnt > 0) { + // move caches from deleted list to standard list + SQLiteStatement moveToStandard = PreparedStatements.getMoveToStandardList(); + moveToStandard.bindLong(1, listId); + moveToStandard.execute(); + + status = true; + } + + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + + return status; + } + + public static void moveToList(final Geocache cache, final int listId) { + moveToList(Collections.singletonList(cache), listId); + } + + public static void moveToList(final List caches, final int listId) { + if (listId == StoredList.ALL_LIST_ID) { + return; + } + if (caches.isEmpty()) { + return; + } + init(); + + SQLiteStatement move = PreparedStatements.getMoveToList(); + + database.beginTransaction(); + try { + for (Geocache cache : caches) { + move.bindLong(1, listId); + move.bindString(2, cache.getGeocode()); + move.execute(); + cache.setListId(listId); + } + database.setTransactionSuccessful(); + } finally { + database.endTransaction(); + } + } + + public static boolean isInitialized() { + return database != null; + } + + public static boolean removeSearchedDestination(Destination destination) { + if (destination == null) { + return false; + } + init(); + + database.beginTransaction(); + try { + database.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null); + database.setTransactionSuccessful(); + return true; + } catch (Exception e) { + Log.e("Unable to remove searched destination", e); + } finally { + database.endTransaction(); + } + + return false; + } + + /** + * Load the lazily initialized fields of a cache and return them as partial cache (all other fields unset). + * + * @param geocode + * @return + */ + public static Geocache loadCacheTexts(final String geocode) { + final Geocache partial = new Geocache(); + + // in case of database issues, we still need to return a result to avoid endless loops + partial.setDescription(StringUtils.EMPTY); + partial.setShortDescription(StringUtils.EMPTY); + partial.setHint(StringUtils.EMPTY); + partial.setLocation(StringUtils.EMPTY); + + init(); + + try { + final Cursor cursor = database.query( + dbTableCaches, + new String[] { "description", "shortdesc", "hint", "location" }, + "geocode = ?", + new String[] { geocode }, + null, + null, + null, + "1"); + + if (cursor.moveToFirst()) { + partial.setDescription(StringUtils.defaultString(cursor.getString(0))); + partial.setShortDescription(StringUtils.defaultString(cursor.getString(1))); + partial.setHint(StringUtils.defaultString(cursor.getString(2))); + partial.setLocation(StringUtils.defaultString(cursor.getString(3))); + } + + cursor.close(); + } catch (SQLiteDoneException e) { + // Do nothing, it only means we have no information on the cache + } catch (Exception e) { + Log.e("DataStore.getCacheDescription", e); + } + + return partial; + } + + /** + * checks if this is a newly created database + */ + public static boolean isNewlyCreatedDatebase() { + return newlyCreatedDatabase; + } + + /** + * resets flag for newly created database to avoid asking the user multiple times + */ + public static void resetNewlyCreatedDatabase() { + newlyCreatedDatabase = false; + } + + /** + * Creates the WHERE clause for matching multiple geocodes. This automatically converts all given codes to + * UPPERCASE. + */ + private static StringBuilder whereGeocodeIn(Set geocodes) { + final StringBuilder where = new StringBuilder(); + + if (geocodes != null && !geocodes.isEmpty()) { + StringBuilder all = new StringBuilder(); + for (String geocode : geocodes) { + if (all.length() > 0) { + all.append(','); + } + all.append(DatabaseUtils.sqlEscapeString(StringUtils.upperCase(geocode))); + } + + where.append("geocode in (").append(all).append(')'); + } + + return where; + } + + /** + * Loads all Waypoints in the coordinate rectangle. + * + * @param excludeDisabled + * @param excludeMine + * @param type + * @return + */ + + public static Set loadWaypoints(final Viewport viewport, boolean excludeMine, boolean excludeDisabled, CacheType type) { + final StringBuilder where = new StringBuilder(buildCoordinateWhere(dbTableWaypoints, viewport)); + if (excludeMine) { + where.append(" and ").append(dbTableCaches).append(".found == 0"); + } + if (excludeDisabled) { + where.append(" and ").append(dbTableCaches).append(".disabled == 0"); + } + if (type != CacheType.ALL) { + where.append(" and ").append(dbTableCaches).append(".type == '").append(type.id).append('\''); + } + init(); + + final StringBuilder query = new StringBuilder("SELECT "); + for (int i = 0; i < WAYPOINT_COLUMNS.length; i++) { + query.append(i > 0 ? ", " : "").append(dbTableWaypoints).append('.').append(WAYPOINT_COLUMNS[i]).append(' '); + } + query.append(" FROM ").append(dbTableWaypoints).append(", ").append(dbTableCaches).append(" WHERE ").append(dbTableWaypoints).append(".geocode == ").append(dbTableCaches).append(".geocode and ").append(where); + + final Set waypoints = new HashSet(); + final Cursor cursor = database.rawQuery(query.toString(), null); + while (cursor.moveToNext()) { + waypoints.add(createWaypointFromDatabaseContent(cursor)); + } + cursor.close(); + return waypoints; + } + + public static String[] getTrackableCodes() { + init(); + + final Cursor cursor = database.query( + dbTableTrackables, + new String[] { "tbcode" }, + null, + null, + null, + null, + "updated DESC", + "100"); + return getFirstColumn(cursor); + } + + /** + * Extract the first column of the cursor rows and close the cursor. + * + * @param cursor a database cursor + * @return the first column of each row + */ + private static String[] getFirstColumn(final Cursor cursor) { + final String[] result = new String[cursor.getCount()]; + for (int i = 0; cursor.moveToNext(); i++) { + result[i] = cursor.getString(0); + } + cursor.close(); + return result; + } + + public static boolean saveChangedCache(Geocache cache) { + return DataStore.saveCache(cache, cache.getStorageLocation().contains(StorageLocation.DATABASE) ? LoadFlags.SAVE_ALL : EnumSet.of(SaveFlag.SAVE_CACHE)); + } + + private static class PreparedStatements { + + private static HashMap statements = new HashMap(); + + public static SQLiteStatement getMoveToStandardList() { + return getStatement("MoveToStandardList", "UPDATE " + dbTableCaches + " SET reason = " + StoredList.STANDARD_LIST_ID + " WHERE reason = ?"); + } + + public static SQLiteStatement getMoveToList() { + return getStatement("MoveToList", "UPDATE " + dbTableCaches + " SET reason = ? WHERE geocode = ?"); + } + + public static SQLiteStatement getUpdateVisitDate() { + return getStatement("UpdateVisitDate", "UPDATE " + dbTableCaches + " SET visiteddate = ? WHERE geocode = ?"); + } + + public static SQLiteStatement getInsertLogImage() { + return getStatement("InsertLogImage", "INSERT INTO " + dbTableLogImages + " (log_id, title, url) VALUES (?, ?, ?)"); + } + + public static SQLiteStatement getInsertLogCounts() { + return getStatement("InsertLogCounts", "INSERT INTO " + dbTableLogCount + " (geocode, updated, type, count) VALUES (?, ?, ?, ?)"); + } + + public static SQLiteStatement getInsertSpoiler() { + return getStatement("InsertSpoiler", "INSERT INTO " + dbTableSpoilers + " (geocode, updated, url, title, description) VALUES (?, ?, ?, ?, ?)"); + } + + public static SQLiteStatement getInsertSearchDestination(Destination destination) { + final SQLiteStatement statement = getStatement("InsertSearch", "INSERT INTO " + dbTableSearchDestionationHistory + " (date, latitude, longitude) VALUES (?, ?, ?)"); + statement.bindLong(1, destination.getDate()); + final Geopoint coords = destination.getCoords(); + statement.bindDouble(2, coords.getLatitude()); + statement.bindDouble(3, coords.getLongitude()); + return statement; + } + + private static void clearPreparedStatements() { + for (SQLiteStatement statement : statements.values()) { + statement.close(); + } + statements.clear(); + } + + private static synchronized SQLiteStatement getStatement(final String key, final String query) { + SQLiteStatement statement = statements.get(key); + if (statement == null) { + init(); + statement = database.compileStatement(query); + statements.put(key, statement); + } + return statement; + } + + public static SQLiteStatement getCountHistoryCaches() { + return getStatement("HistoryCount", "select count(_id) from " + dbTableCaches + " where visiteddate > 0"); + } + + private static SQLiteStatement getLogCountOfGeocode() { + return getStatement("LogCountFromGeocode", "SELECT count(_id) FROM " + DataStore.dbTableLogsOffline + " WHERE geocode = ?"); + } + + private static SQLiteStatement getCountCachesOnStandardList() { + return getStatement("CountStandardList", "SELECT count(_id) FROM " + dbTableCaches + " WHERE reason = " + StoredList.STANDARD_LIST_ID); + } + + private static SQLiteStatement getCountAllCaches() { + return getStatement("CountAllLists", "SELECT count(_id) FROM " + dbTableCaches + " WHERE reason >= " + StoredList.STANDARD_LIST_ID); + } + + private static SQLiteStatement getInsertLog() { + return getStatement("InsertLog", "INSERT INTO " + dbTableLogs + " (geocode, updated, type, author, log, date, found, friend) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + } + + private static SQLiteStatement getInsertAttribute() { + return getStatement("InsertAttribute", "INSERT INTO " + dbTableAttributes + " (geocode, updated, attribute) VALUES (?, ?, ?)"); + } + + private static SQLiteStatement getListIdOfGeocode() { + return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE geocode = ?"); + } + + private static SQLiteStatement getListIdOfGuid() { + return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE guid = ?"); + } + + private static SQLiteStatement getCacheIdOfGeocode() { + return getStatement("cacheIdFromGeocode", "SELECT cacheid FROM " + dbTableCaches + " WHERE geocode = ?"); + } + + private static SQLiteStatement getGeocodeOfGuid() { + return getStatement("geocodeFromGuid", "SELECT geocode FROM " + dbTableCaches + " WHERE guid = ?"); + } + + } + + public static void saveVisitDate(final String geocode) { + setVisitDate(Collections.singletonList(geocode), System.currentTimeMillis()); + } + + public static void markDropped(List caches) { + moveToList(caches, StoredList.TEMPORARY_LIST_ID); + } + + public static Viewport getBounds(String geocode) { + if (geocode == null) { + return null; + } + + return DataStore.getBounds(Collections.singleton(geocode)); + } + + public static void clearVisitDate(String[] selected) { + setVisitDate(Arrays.asList(selected), 0); + } + + public static SearchResult getBatchOfStoredCaches(Geopoint coords, CacheType cacheType, int listId) { + final Set geocodes = DataStore.loadBatchOfStoredGeocodes(coords, cacheType, listId); + return new SearchResult(geocodes, DataStore.getAllStoredCachesCount(cacheType, listId)); + } + + public static SearchResult getHistoryOfCaches(boolean detailedOnly, CacheType cacheType) { + final Set geocodes = DataStore.loadBatchOfHistoricGeocodes(detailedOnly, cacheType); + return new SearchResult(geocodes, DataStore.getAllHistoryCachesCount()); + } + + public static boolean saveWaypoint(int id, String geocode, Waypoint waypoint) { + if (DataStore.saveWaypointInternal(id, geocode, waypoint)) { + DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + return true; + } + return false; + } + + public static Set getCachedMissingFromSearch(final SearchResult searchResult, final Set tiles, final IConnector connector, final int maxZoom) { + + // get cached cgeocaches + final Set cachedGeocodes = new HashSet(); + for (Tile tile : tiles) { + cachedGeocodes.addAll(cacheCache.getInViewport(tile.getViewport(), CacheType.ALL)); + } + // remove found in search result + cachedGeocodes.removeAll(searchResult.getGeocodes()); + + // check remaining against viewports + Set missingFromSearch = new HashSet(); + for (String geocode : cachedGeocodes) { + if (connector.canHandle(geocode)) { + Geocache geocache = cacheCache.getCacheFromCache(geocode); + if (geocache.getCoordZoomLevel() <= maxZoom) { + boolean found = false; + for (Tile tile : tiles) { + if (tile.containsPoint(geocache)) { + found = true; + break; + } + } + if (found) { + missingFromSearch.add(geocode); + } + } + } + } + + return missingFromSearch; + } + +} diff --git a/main/src/cgeo/geocaching/EditWaypointActivity.java b/main/src/cgeo/geocaching/EditWaypointActivity.java index 59666e9..11d15da 100644 --- a/main/src/cgeo/geocaching/EditWaypointActivity.java +++ b/main/src/cgeo/geocaching/EditWaypointActivity.java @@ -107,7 +107,7 @@ public class EditWaypointActivity extends AbstractActivity { note.setText(StringUtils.trimToEmpty(waypoint.getNote())); } } - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_ONLY); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_ONLY); setCoordsModificationVisibility(ConnectorFactory.getConnector(geocode), cache); } @@ -168,7 +168,7 @@ public class EditWaypointActivity extends AbstractActivity { initializeWaypointTypeSelector(); if (geocode != null) { - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); setCoordsModificationVisibility(ConnectorFactory.getConnector(geocode), cache); } } @@ -259,7 +259,7 @@ public class EditWaypointActivity extends AbstractActivity { @Override public void run() { try { - waypoint = cgData.loadWaypoint(id); + waypoint = DataStore.loadWaypoint(id); loadWaypointHandler.sendMessage(Message.obtain()); } catch (Exception e) { @@ -278,7 +278,7 @@ public class EditWaypointActivity extends AbstractActivity { } catch (Geopoint.ParseException e) { // button text is blank when creating new waypoint } - Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); CoordinatesInputDialog coordsDialog = new CoordinatesInputDialog(EditWaypointActivity.this, cache, gp, app.currentGeo()); coordsDialog.setCancelable(true); coordsDialog.setOnCoordinateUpdate(new CoordinatesInputDialog.CoordinateUpdate() { @@ -416,14 +416,14 @@ public class EditWaypointActivity extends AbstractActivity { waypoint.setVisited(visited); waypoint.setId(id); - Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); if (cache == null) { finishHandler.sendEmptyMessage(SAVE_ERROR); return null; } Waypoint oldWaypoint = cache.getWaypointById(id); if (cache.addOrChangeWaypoint(waypoint, true)) { - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); if (!StaticMapsProvider.hasAllStaticMapsForWaypoint(geocode, waypoint)) { StaticMapsProvider.removeWpStaticMaps(oldWaypoint, geocode); if (Settings.isStoreOfflineWpMaps()) { @@ -438,7 +438,7 @@ public class EditWaypointActivity extends AbstractActivity { cache.setUserModifiedCoords(true); } cache.setCoords(waypoint.getCoords()); - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } if (modifyBoth.isChecked() && waypoint.getCoords() != null) { finishHandler.sendEmptyMessage(UPLOAD_START); diff --git a/main/src/cgeo/geocaching/Geocache.java b/main/src/cgeo/geocaching/Geocache.java index 7aceed4..94de3b4 100644 --- a/main/src/cgeo/geocaching/Geocache.java +++ b/main/src/cgeo/geocaching/Geocache.java @@ -1,6 +1,6 @@ package cgeo.geocaching; -import cgeo.geocaching.cgData.StorageLocation; +import cgeo.geocaching.DataStore.StorageLocation; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; @@ -112,20 +112,20 @@ public class Geocache implements ICache, IWaypoint { private final List attributes = new LazyInitializedList() { @Override public List call() { - return cgData.loadAttributes(geocode); + return DataStore.loadAttributes(geocode); } }; private final List waypoints = new LazyInitializedList() { @Override public List call() { - return cgData.loadWaypoints(geocode); + return DataStore.loadWaypoints(geocode); } }; private List spoilers = null; private final List logs = new LazyInitializedList() { @Override public List call() { - return cgData.loadLogs(geocode); + return DataStore.loadLogs(geocode); } }; private List inventory = null; @@ -469,12 +469,12 @@ public class Geocache implements ICache, IWaypoint { if (logType == LogType.UNKNOWN) { return; } - final boolean status = cgData.saveLogOffline(geocode, date.getTime(), logType, log); + final boolean status = DataStore.saveLogOffline(geocode, date.getTime(), logType, log); final Resources res = fromActivity.getResources(); if (status) { ActivityMixin.showToast(fromActivity, res.getString(R.string.info_log_saved)); - cgData.saveVisitDate(geocode); + DataStore.saveVisitDate(geocode); logOffline = Boolean.TRUE; notifyChange(); @@ -484,7 +484,7 @@ public class Geocache implements ICache, IWaypoint { } public void clearOfflineLog() { - cgData.clearLogOffline(geocode); + DataStore.clearLogOffline(geocode); notifyChange(); } @@ -664,7 +664,7 @@ public class Geocache implements ICache, IWaypoint { */ private void initializeCacheTexts() { if (description == null || shortdesc == null || hint == null || location == null) { - final Geocache partial = cgData.loadCacheTexts(this.getGeocode()); + final Geocache partial = DataStore.loadCacheTexts(this.getGeocode()); if (description == null) { setDescription(partial.getDescription()); } @@ -1028,7 +1028,7 @@ public class Geocache implements ICache, IWaypoint { } } } - return saveToDatabase && cgData.saveWaypoints(this); + return saveToDatabase && DataStore.saveWaypoints(this); } /** @@ -1244,7 +1244,7 @@ public class Geocache implements ICache, IWaypoint { // when waypoint was edited, finalDefined may have changed resetFinalDefined(); } - return saveToDatabase && cgData.saveWaypoint(waypoint.getId(), geocode, waypoint); + return saveToDatabase && DataStore.saveWaypoint(waypoint.getId(), geocode, waypoint); } public boolean hasWaypoints() { @@ -1297,7 +1297,7 @@ public class Geocache implements ICache, IWaypoint { copy.setUserDefined(); copy.setName(cgeoapplication.getInstance().getString(R.string.waypoint_copy_of) + " " + copy.getName()); waypoints.add(index + 1, copy); - return cgData.saveWaypoint(-1, geocode, copy); + return DataStore.saveWaypoint(-1, geocode, copy); } /** @@ -1317,8 +1317,8 @@ public class Geocache implements ICache, IWaypoint { if (waypoint.isUserDefined()) { final int index = getWaypointIndex(waypoint); waypoints.remove(index); - cgData.deleteWaypoint(waypoint.getId()); - cgData.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + DataStore.deleteWaypoint(waypoint.getId()); + DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); // Check status if Final is defined if (waypoint.isFinalWithCoords()) { resetFinalDefined(); @@ -1337,8 +1337,8 @@ public class Geocache implements ICache, IWaypoint { public void deleteWaypointForce(Waypoint waypoint) { final int index = getWaypointIndex(waypoint); waypoints.remove(index); - cgData.deleteWaypoint(waypoint.getId()); - cgData.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + DataStore.deleteWaypoint(waypoint.getId()); + DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); resetFinalDefined(); } @@ -1511,8 +1511,8 @@ public class Geocache implements ICache, IWaypoint { public void drop(Handler handler) { try { - cgData.markDropped(Collections.singletonList(this)); - cgData.removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE)); + DataStore.markDropped(Collections.singletonList(this)); + DataStore.removeCache(getGeocode(), EnumSet.of(RemoveFlag.REMOVE_CACHE)); handler.sendMessage(Message.obtain()); } catch (final Exception e) { @@ -1563,7 +1563,7 @@ public class Geocache implements ICache, IWaypoint { } public void refresh(int newListId, CancellableHandler handler) { - cgData.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + DataStore.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); storeCache(null, geocode, newListId, true, handler); } @@ -1639,7 +1639,7 @@ public class Geocache implements ICache, IWaypoint { } cache.setListId(listId); - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); if (CancellableHandler.isCancelled(handler)) { return; @@ -1661,9 +1661,9 @@ public class Geocache implements ICache, IWaypoint { return null; } - if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (cgData.isOffline(geocode, guid) || cgData.isThere(geocode, guid, true, true))) { + if (!forceReload && listId == StoredList.TEMPORARY_LIST_ID && (DataStore.isOffline(geocode, guid) || DataStore.isThere(geocode, guid, true, true))) { final SearchResult search = new SearchResult(); - final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : cgData.getGeocodeForGuid(guid); + final String realGeocode = StringUtils.isNotBlank(geocode) ? geocode : DataStore.getGeocodeForGuid(guid); search.addGeocode(realGeocode); return search; } @@ -1735,7 +1735,7 @@ public class Geocache implements ICache, IWaypoint { * @return */ public boolean hasAttribute(CacheAttribute attribute, boolean yes) { - Geocache fullCache = cgData.loadCache(getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); + Geocache fullCache = DataStore.loadCache(getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); if (fullCache == null) { fullCache = this; } diff --git a/main/src/cgeo/geocaching/ImagesActivity.java b/main/src/cgeo/geocaching/ImagesActivity.java index 0b80d53..5eeb621 100644 --- a/main/src/cgeo/geocaching/ImagesActivity.java +++ b/main/src/cgeo/geocaching/ImagesActivity.java @@ -58,7 +58,7 @@ public class ImagesActivity extends AbstractActivity { return; } - offline = cgData.isOffline(geocode, null) && (imgType == ImageType.SpoilerImages + offline = DataStore.isOffline(geocode, null) && (imgType == ImageType.SpoilerImages || Settings.isStoreLogImages()); } diff --git a/main/src/cgeo/geocaching/LogCacheActivity.java b/main/src/cgeo/geocaching/LogCacheActivity.java index cb565bd..8c3ef44 100644 --- a/main/src/cgeo/geocaching/LogCacheActivity.java +++ b/main/src/cgeo/geocaching/LogCacheActivity.java @@ -234,13 +234,13 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia } if ((StringUtils.isBlank(cacheid)) && StringUtils.isNotBlank(geocode)) { - cacheid = cgData.getCacheidForGeocode(geocode); + cacheid = DataStore.getCacheidForGeocode(geocode); } if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(cacheid)) { - geocode = cgData.getGeocodeForGuid(cacheid); + geocode = DataStore.getGeocodeForGuid(cacheid); } - cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); possibleLogTypes = cache.getPossibleLogTypes(); if (StringUtils.isNotBlank(cache.getName())) { @@ -268,7 +268,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia imageUri = Uri.parse(savedInstanceState.getString(SAVED_STATE_IMAGE_URI)); } else { // If log had been previously saved, load it now, otherwise initialize signature as needed - final LogEntry log = cgData.loadLogOffline(geocode); + final LogEntry log = DataStore.loadLogOffline(geocode); if (log != null) { typeSelected = log.type; date.setTime(new Date(log.date)); @@ -542,7 +542,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia cache.setVisitedDate(new Date().getTime()); } - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); cache.clearOfflineLog(); if (typeSelected == LogType.FOUND_IT) { @@ -559,7 +559,7 @@ public class LogCacheActivity extends AbstractLoggingActivity implements DateDia final String uploadedImageUrl = imageResult.getImageUri(); if (StringUtils.isNotEmpty(uploadedImageUrl)) { logNow.addLogImage(new Image(uploadedImageUrl, imageCaption, imageDescription)); - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return imageResult.getPostResult(); } diff --git a/main/src/cgeo/geocaching/LogTrackableActivity.java b/main/src/cgeo/geocaching/LogTrackableActivity.java index a45d584..129ae2a 100644 --- a/main/src/cgeo/geocaching/LogTrackableActivity.java +++ b/main/src/cgeo/geocaching/LogTrackableActivity.java @@ -130,7 +130,7 @@ public class LogTrackableActivity extends AbstractLoggingActivity implements Dat } } - trackable = cgData.loadTrackable(geocode); + trackable = DataStore.loadTrackable(geocode); if (StringUtils.isNotBlank(trackable.getName())) { setTitle(res.getString(R.string.trackable_touch) + ": " + trackable.getName()); diff --git a/main/src/cgeo/geocaching/MainActivity.java b/main/src/cgeo/geocaching/MainActivity.java index b6f267a..e4955b5 100644 --- a/main/src/cgeo/geocaching/MainActivity.java +++ b/main/src/cgeo/geocaching/MainActivity.java @@ -469,7 +469,7 @@ public class MainActivity extends AbstractActivity { } private void checkRestore() { - if (!cgData.isNewlyCreatedDatebase() || null == DatabaseBackupUtils.getRestoreFile()) { + if (!DataStore.isNewlyCreatedDatebase() || null == DatabaseBackupUtils.getRestoreFile()) { return; } new AlertDialog.Builder(this) @@ -480,7 +480,7 @@ public class MainActivity extends AbstractActivity { @Override public void onClick(final DialogInterface dialog, final int id) { dialog.dismiss(); - cgData.resetNewlyCreatedDatabase(); + DataStore.resetNewlyCreatedDatabase(); DatabaseBackupUtils.restoreDatabase(MainActivity.this); } }) @@ -488,7 +488,7 @@ public class MainActivity extends AbstractActivity { @Override public void onClick(final DialogInterface dialog, final int id) { dialog.cancel(); - cgData.resetNewlyCreatedDatabase(); + DataStore.resetNewlyCreatedDatabase(); } }) .create() @@ -641,7 +641,7 @@ public class MainActivity extends AbstractActivity { } int checks = 0; - while (!cgData.isInitialized()) { + while (!DataStore.isInitialized()) { try { wait(500); checks++; @@ -654,7 +654,7 @@ public class MainActivity extends AbstractActivity { } } - countBubbleCnt = cgData.getAllCachesCount(); + countBubbleCnt = DataStore.getAllCachesCount(); countBubbleHandler.sendEmptyMessage(0); } @@ -679,7 +679,7 @@ public class MainActivity extends AbstractActivity { } cleanupRunning = true; - cgData.clean(more); + DataStore.clean(more); cleanupRunning = false; if (version > 0) { diff --git a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java index 87d7ba7..fa81e73 100644 --- a/main/src/cgeo/geocaching/NavigateAnyPointActivity.java +++ b/main/src/cgeo/geocaching/NavigateAnyPointActivity.java @@ -214,7 +214,7 @@ public class NavigateAnyPointActivity extends AbstractActivity { private List getHistoryOfSearchedLocations() { if (historyOfSearchedLocations == null) { // Load from database - historyOfSearchedLocations = cgData.loadHistoryOfSearchedLocations(); + historyOfSearchedLocations = DataStore.loadHistoryOfSearchedLocations(); } return historyOfSearchedLocations; @@ -377,7 +377,7 @@ public class NavigateAnyPointActivity extends AbstractActivity { getHistoryOfSearchedLocations().add(0, loc); // Save location - cgData.saveSearchedDestination(loc); + DataStore.saveSearchedDestination(loc); // Ensure to remove the footer historyListView.removeFooterView(getEmptyHistoryFooter()); @@ -396,7 +396,7 @@ public class NavigateAnyPointActivity extends AbstractActivity { getHistoryOfSearchedLocations().remove(destination); // Save - cgData.removeSearchedDestination(destination); + DataStore.removeSearchedDestination(destination); if (getHistoryOfSearchedLocations().isEmpty()) { if (historyListView.getFooterViewsCount() == 0) { @@ -415,7 +415,7 @@ public class NavigateAnyPointActivity extends AbstractActivity { getHistoryOfSearchedLocations().clear(); // Save - cgData.clearSearchedDestinations(); + DataStore.clearSearchedDestinations(); if (historyListView.getFooterViewsCount() == 0) { historyListView.addFooterView(getEmptyHistoryFooter()); diff --git a/main/src/cgeo/geocaching/SearchActivity.java b/main/src/cgeo/geocaching/SearchActivity.java index 8f58bcd..dc204d0 100644 --- a/main/src/cgeo/geocaching/SearchActivity.java +++ b/main/src/cgeo/geocaching/SearchActivity.java @@ -171,7 +171,7 @@ public class SearchActivity extends AbstractActivity { findByGeocodeFn(); } }); - addHistoryEntries(geocodeEdit, cgData.getRecentGeocodesForSearch()); + addHistoryEntries(geocodeEdit, DataStore.getRecentGeocodesForSearch()); displayByGeocode.setOnClickListener(new FindByGeocodeListener()); EditUtils.setActionListener((EditText) findViewById(R.id.keyword), new Runnable() { @@ -214,7 +214,7 @@ public class SearchActivity extends AbstractActivity { findTrackableFn(); } }); - addHistoryEntries(trackable, cgData.getTrackableCodes()); + addHistoryEntries(trackable, DataStore.getTrackableCodes()); disableSuggestions(trackable); displayTrackable.setOnClickListener(new FindTrackableListener()); } diff --git a/main/src/cgeo/geocaching/SearchResult.java b/main/src/cgeo/geocaching/SearchResult.java index e637d1f..add7ce2 100644 --- a/main/src/cgeo/geocaching/SearchResult.java +++ b/main/src/cgeo/geocaching/SearchResult.java @@ -199,7 +199,7 @@ public class SearchResult implements Parcelable { SearchResult result = new SearchResult(this); result.geocodes.clear(); final ArrayList cachesForVote = new ArrayList(); - final Set caches = cgData.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); + final Set caches = DataStore.loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); int excluded = 0; for (Geocache cache : caches) { // Is there any reason to exclude the cache from the list? @@ -220,11 +220,11 @@ public class SearchResult implements Parcelable { } public Geocache getFirstCacheFromResult(final EnumSet loadFlags) { - return CollectionUtils.isNotEmpty(geocodes) ? cgData.loadCache(geocodes.iterator().next(), loadFlags) : null; + return CollectionUtils.isNotEmpty(geocodes) ? DataStore.loadCache(geocodes.iterator().next(), loadFlags) : null; } public Set getCachesFromSearchResult(final EnumSet loadFlags) { - return cgData.loadCaches(geocodes, loadFlags); + return DataStore.loadCaches(geocodes, loadFlags); } /** Add the geocode to the search. No cache is loaded into the CacheCache */ @@ -243,7 +243,7 @@ public class SearchResult implements Parcelable { /** Add the cache geocode to the search and store the cache in the CacheCache */ public boolean addAndPutInCache(final Geocache cache) { addGeocode(cache.getGeocode()); - return cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); + return DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); } public boolean isEmpty() { @@ -252,7 +252,7 @@ public class SearchResult implements Parcelable { public boolean hasUnsavedCaches() { for (final String geocode : getGeocodes()) { - if (!cgData.isOffline(geocode, null)) { + if (!DataStore.isOffline(geocode, null)) { return true; } } diff --git a/main/src/cgeo/geocaching/StaticMapsActivity.java b/main/src/cgeo/geocaching/StaticMapsActivity.java index 2268df9..0f03b34 100644 --- a/main/src/cgeo/geocaching/StaticMapsActivity.java +++ b/main/src/cgeo/geocaching/StaticMapsActivity.java @@ -117,7 +117,7 @@ public class StaticMapsActivity extends AbstractActivity { for (int level = 1; level <= StaticMapsProvider.MAPS_LEVEL_MAX; level++) { try { if (waypointId != null) { - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); final Bitmap image = StaticMapsProvider.getWaypointMap(geocode, cache.getWaypointById(waypointId), level); if (image != null) { maps.add(image); @@ -151,7 +151,7 @@ public class StaticMapsActivity extends AbstractActivity { } private boolean downloadStaticMaps() { - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); if (waypointId == null) { showToast(res.getString(R.string.info_storing_static_maps)); StaticMapsProvider.storeCacheStaticMap(cache, true); diff --git a/main/src/cgeo/geocaching/StoredList.java b/main/src/cgeo/geocaching/StoredList.java index 6f49625..1084a4b 100644 --- a/main/src/cgeo/geocaching/StoredList.java +++ b/main/src/cgeo/geocaching/StoredList.java @@ -80,7 +80,7 @@ public final class StoredList { final List lists = getSortedLists(); if (exceptListId > StoredList.TEMPORARY_LIST_ID) { - StoredList exceptList = cgData.getList(exceptListId); + StoredList exceptList = DataStore.getList(exceptListId); if (exceptList != null) { lists.remove(exceptList); } @@ -122,7 +122,7 @@ public final class StoredList { @NonNull private static List getSortedLists() { final Collator collator = Collator.getInstance(); - final List lists = cgData.getLists(); + final List lists = DataStore.getLists(); Collections.sort(lists, new Comparator() { @Override @@ -146,9 +146,9 @@ public final class StoredList { @Override public void run(final String listName) { - final int newId = cgData.createList(listName); + final int newId = DataStore.createList(listName); - if (newId >= cgData.customListIdOffset) { + if (newId >= DataStore.customListIdOffset) { ActivityMixin.showToast(activity, res.getString(R.string.list_dialog_create_ok)); if (runAfterwards != null) { runAfterwards.run(newId); @@ -189,12 +189,12 @@ public final class StoredList { } public void promptForListRename(final int listId, final Runnable runAfterRename) { - final StoredList list = cgData.getList(listId); + final StoredList list = DataStore.getList(listId); handleListNameInput(list.title, R.string.list_dialog_rename_title, R.string.list_dialog_rename, new RunnableWithArgument() { @Override public void run(final String listName) { - cgData.renameList(listId, listName); + DataStore.renameList(listId, listName); if (runAfterRename != null) { runAfterRename.run(); } diff --git a/main/src/cgeo/geocaching/TrackableActivity.java b/main/src/cgeo/geocaching/TrackableActivity.java index 20a9ccf..1ab428e 100644 --- a/main/src/cgeo/geocaching/TrackableActivity.java +++ b/main/src/cgeo/geocaching/TrackableActivity.java @@ -233,7 +233,7 @@ public class TrackableActivity extends AbstractViewPagerActivity 0) { - db.execSQL("delete from " + dbTableCaches + " where reason = 0"); - - if (oldVersion < 52) { // upgrade to 52 - try { - db.execSQL(dbCreateSearchDestinationHistory); - - Log.i("Added table " + dbTableSearchDestionationHistory + "."); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 52", e); - } - } - - if (oldVersion < 53) { // upgrade to 53 - try { - db.execSQL("alter table " + dbTableCaches + " add column onWatchlist integer"); - - Log.i("Column onWatchlist added to " + dbTableCaches + "."); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 53", e); - } - } - - if (oldVersion < 54) { // update to 54 - try { - db.execSQL(dbCreateLogImages); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 54", e); - - } - } - - if (oldVersion < 55) { // update to 55 - try { - db.execSQL("alter table " + dbTableCaches + " add column personal_note text"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 55", e); - } - } - - // make all internal attribute names lowercase - // @see issue #299 - if (oldVersion < 56) { // update to 56 - try { - db.execSQL("update " + dbTableAttributes + " set attribute = " + - "lower(attribute) where attribute like \"%_yes\" " + - "or attribute like \"%_no\""); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 56", e); - } - } - - // Create missing indices. See issue #435 - if (oldVersion < 57) { // update to 57 - try { - db.execSQL("drop index in_a"); - db.execSQL("drop index in_b"); - db.execSQL("drop index in_c"); - db.execSQL("drop index in_d"); - db.execSQL("drop index in_e"); - db.execSQL("drop index in_f"); - createIndices(db); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 57", e); - } - } - - if (oldVersion < 58) { // upgrade to 58 - try { - db.beginTransaction(); - - final String dbTableCachesTemp = dbTableCaches + "_temp"; - final String dbCreateCachesTemp = "" - + "create table " + dbTableCachesTemp + " (" - + "_id integer primary key autoincrement, " - + "updated long not null, " - + "detailed integer not null default 0, " - + "detailedupdate long, " - + "visiteddate long, " - + "geocode text unique not null, " - + "reason integer not null default 0, " - + "cacheid text, " - + "guid text, " - + "type text, " - + "name text, " - + "own integer not null default 0, " - + "owner text, " - + "owner_real text, " - + "hidden long, " - + "hint text, " - + "size text, " - + "difficulty float, " - + "terrain float, " - + "latlon text, " - + "location text, " - + "direction double, " - + "distance double, " - + "latitude double, " - + "longitude double, " - + "reliable_latlon integer, " - + "personal_note text, " - + "shortdesc text, " - + "description text, " - + "favourite_cnt integer, " - + "rating float, " - + "votes integer, " - + "myvote float, " - + "disabled integer not null default 0, " - + "archived integer not null default 0, " - + "members integer not null default 0, " - + "found integer not null default 0, " - + "favourite integer not null default 0, " - + "inventorycoins integer default 0, " - + "inventorytags integer default 0, " - + "inventoryunknown integer default 0, " - + "onWatchlist integer default 0 " - + "); "; - - db.execSQL(dbCreateCachesTemp); - db.execSQL("insert into " + dbTableCachesTemp + " select _id,updated,detailed,detailedupdate,visiteddate,geocode,reason,cacheid,guid,type,name,own,owner,owner_real," + - "hidden,hint,size,difficulty,terrain,latlon,location,direction,distance,latitude,longitude, 0," + - "personal_note,shortdesc,description,favourite_cnt,rating,votes,myvote,disabled,archived,members,found,favourite,inventorycoins," + - "inventorytags,inventoryunknown,onWatchlist from " + dbTableCaches); - db.execSQL("drop table " + dbTableCaches); - db.execSQL("alter table " + dbTableCachesTemp + " rename to " + dbTableCaches); - - final String dbTableWaypointsTemp = dbTableWaypoints + "_temp"; - final String dbCreateWaypointsTemp = "" - + "create table " + dbTableWaypointsTemp + " (" - + "_id integer primary key autoincrement, " - + "geocode text not null, " - + "updated long not null, " // date of save - + "type text not null default 'waypoint', " - + "prefix text, " - + "lookup text, " - + "name text, " - + "latlon text, " - + "latitude double, " - + "longitude double, " - + "note text " - + "); "; - db.execSQL(dbCreateWaypointsTemp); - db.execSQL("insert into " + dbTableWaypointsTemp + " select _id, geocode, updated, type, prefix, lookup, name, latlon, latitude, longitude, note from " + dbTableWaypoints); - db.execSQL("drop table " + dbTableWaypoints); - db.execSQL("alter table " + dbTableWaypointsTemp + " rename to " + dbTableWaypoints); - - createIndices(db); - - db.setTransactionSuccessful(); - - Log.i("Removed latitude_string and longitude_string columns"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 58", e); - } finally { - db.endTransaction(); - } - } - - if (oldVersion < 59) { - try { - // Add new indices and remove obsolete cache files - createIndices(db); - removeObsoleteCacheDirectories(db); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 59", e); - } - } - - if (oldVersion < 60) { - try { - removeSecEmptyDirs(); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 60", e); - } - } - if (oldVersion < 61) { - try { - db.execSQL("alter table " + dbTableLogs + " add column friend integer"); - db.execSQL("alter table " + dbTableCaches + " add column coordsChanged integer default 0"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 61", e); - - } - } - // Introduces finalDefined on caches and own on waypoints - if (oldVersion < 62) { - try { - db.execSQL("alter table " + dbTableCaches + " add column finalDefined integer default 0"); - db.execSQL("alter table " + dbTableWaypoints + " add column own integer default 0"); - db.execSQL("update " + dbTableWaypoints + " set own = 1 where type = 'own'"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 62", e); - - } - } - if (oldVersion < 63) { - try { - removeDoubleUnderscoreMapFiles(); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 63", e); - - } - } - - if (oldVersion < 64) { - try { - // No cache should ever be stored into the ALL_CACHES list. Here we use hardcoded list ids - // rather than symbolic ones because the fix must be applied with the values at the time - // of the problem. The problem was introduced in release 2012.06.01. - db.execSQL("update " + dbTableCaches + " set reason=1 where reason=2"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 64", e); - } - } - - if (oldVersion < 65) { - try { - // Set all waypoints where name is Original coordinates to type ORIGINAL - db.execSQL("update " + dbTableWaypoints + " set type='original', own=0 where name='Original Coordinates'"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 65:", e); - } - } - // Introduces visited feature on waypoints - if (oldVersion < 66) { - try { - db.execSQL("alter table " + dbTableWaypoints + " add column visited integer default 0"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 66", e); - - } - } - // issue2662 OC: Leichtes Klettern / Easy climbing - if (oldVersion < 67) { - try { - db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_yes' where geocode like 'OC%' and attribute = 'climbing_yes'"); - db.execSQL("update " + dbTableAttributes + " set attribute = 'easy_climbing_no' where geocode like 'OC%' and attribute = 'climbing_no'"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 67", e); - - } - } - // Introduces logPasswordRequired on caches - if (oldVersion < 68) { - try { - db.execSQL("alter table " + dbTableCaches + " add column logPasswordRequired integer default 0"); - } catch (Exception e) { - Log.e("Failed to upgrade to ver. 68", e); - - } - } - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - - Log.i("Upgrade database from ver. " + oldVersion + " to ver. " + newVersion + ": completed"); - } - - @Override - public void onOpen(final SQLiteDatabase db) { - if (firstRun) { - sanityChecks(db); - firstRun = false; - } - } - - /** - * Execute sanity checks that should be performed once per application after the database has been - * opened. - * - * @param db the database to perform sanity checks against - */ - private static void sanityChecks(final SQLiteDatabase db) { - // Check that the history of searches is well formed as some dates seem to be missing according - // to NPE traces. - final int staleHistorySearches = db.delete(dbTableSearchDestionationHistory, "date is null", null); - if (staleHistorySearches > 0) { - Log.w(String.format(Locale.getDefault(), "cgData.dbHelper.onOpen: removed %d bad search history entries", staleHistorySearches)); - } - } - - /** - * Method to remove static map files with double underscore due to issue#1670 - * introduced with release on 2012-05-24. - */ - private static void removeDoubleUnderscoreMapFiles() { - File[] geocodeDirs = LocalStorage.getStorage().listFiles(); - final FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String filename) { - return filename.startsWith("map_") && filename.contains("__"); - } - }; - for (final File dir : geocodeDirs) { - final File[] wrongFiles = dir.listFiles(filter); - if (wrongFiles != null) { - for (final File wrongFile : wrongFiles) { - FileUtils.deleteIgnoringFailure(wrongFile); - } - } - } - } - } - - /** - * Remove obsolete cache directories in c:geo private storage. - * - * @param db - * the read-write database to use - */ - private static void removeObsoleteCacheDirectories(final SQLiteDatabase db) { - final Pattern oldFilePattern = Pattern.compile("^[GC|TB|O][A-Z0-9]{4,7}$"); - final SQLiteStatement select = db.compileStatement("select count(*) from " + dbTableCaches + " where geocode = ?"); - final File[] files = LocalStorage.getStorage().listFiles(); - final ArrayList toRemove = new ArrayList(files.length); - for (final File file : files) { - if (file.isDirectory()) { - final String geocode = file.getName(); - if (oldFilePattern.matcher(geocode).find()) { - select.bindString(1, geocode); - if (select.simpleQueryForLong() == 0) { - toRemove.add(file); - } - } - } - } - - // Use a background thread for the real removal to avoid keeping the database locked - // if we are called from within a transaction. - new Thread(new Runnable() { - @Override - public void run() { - for (final File dir : toRemove) { - Log.i("Removing obsolete cache directory for " + dir.getName()); - LocalStorage.deleteDirectory(dir); - } - } - }).start(); - } - - /* - * Remove empty directories created in the secondary storage area. - */ - private static void removeSecEmptyDirs() { - for (final File file : LocalStorage.getStorageSec().listFiles()) { - if (file.isDirectory()) { - // This will silently fail if the directory is not empty. - FileUtils.deleteIgnoringFailure(file); - } - } - } - - private static void dropDatabase(SQLiteDatabase db) { - db.execSQL("drop table if exists " + dbTableCaches); - db.execSQL("drop table if exists " + dbTableAttributes); - db.execSQL("drop table if exists " + dbTableWaypoints); - db.execSQL("drop table if exists " + dbTableSpoilers); - db.execSQL("drop table if exists " + dbTableLogs); - db.execSQL("drop table if exists " + dbTableLogCount); - db.execSQL("drop table if exists " + dbTableLogsOffline); - db.execSQL("drop table if exists " + dbTableTrackables); - } - - public static String[] getRecentGeocodesForSearch() { - init(); - - try { - long timestamp = System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED; - final Cursor cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - "(detailed = 1 and detailedupdate > ?) or reason > 0", - new String[]{Long.toString(timestamp)}, - null, - null, - "detailedupdate desc", - "100"); - - return getFirstColumn(cursor); - } catch (final Exception e) { - Log.e("cgData.allDetailedThere", e); - return new String[0]; - } - } - - public static boolean isThere(String geocode, String guid, boolean detailed, boolean checkTime) { - init(); - - long dataUpdated = 0; - long dataDetailedUpdate = 0; - int dataDetailed = 0; - - try { - Cursor cursor; - - if (StringUtils.isNotBlank(geocode)) { - cursor = database.query( - dbTableCaches, - new String[]{"detailed", "detailedupdate", "updated"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - null, - "1"); - } else if (StringUtils.isNotBlank(guid)) { - cursor = database.query( - dbTableCaches, - new String[]{"detailed", "detailedupdate", "updated"}, - "guid = ?", - new String[]{guid}, - null, - null, - null, - "1"); - } else { - return false; - } - - if (cursor.moveToFirst()) { - dataDetailed = cursor.getInt(0); - dataDetailedUpdate = cursor.getLong(1); - dataUpdated = cursor.getLong(2); - } - - cursor.close(); - } catch (final Exception e) { - Log.e("cgData.isThere", e); - } - - if (detailed && dataDetailed == 0) { - // we want details, but these are not stored - return false; - } - - if (checkTime && detailed && dataDetailedUpdate < (System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED)) { - // we want to check time for detailed cache, but data are older than 3 hours - return false; - } - - if (checkTime && !detailed && dataUpdated < (System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED)) { - // we want to check time for short cache, but data are older than 3 hours - return false; - } - - // we have some cache - return true; - } - - /** is cache stored in one of the lists (not only temporary) */ - public static boolean isOffline(String geocode, String guid) { - if (StringUtils.isBlank(geocode) && StringUtils.isBlank(guid)) { - return false; - } - init(); - - try { - final SQLiteStatement listId; - final String value; - if (StringUtils.isNotBlank(geocode)) { - listId = PreparedStatements.getListIdOfGeocode(); - value = geocode; - } - else { - listId = PreparedStatements.getListIdOfGuid(); - value = guid; - } - synchronized (listId) { - listId.bindString(1, value); - return listId.simpleQueryForLong() != StoredList.TEMPORARY_LIST_ID; - } - } catch (SQLiteDoneException e) { - // Do nothing, it only means we have no information on the cache - } catch (Exception e) { - Log.e("cgData.isOffline", e); - } - - return false; - } - - public static String getGeocodeForGuid(String guid) { - if (StringUtils.isBlank(guid)) { - return null; - } - init(); - - try { - final SQLiteStatement description = PreparedStatements.getGeocodeOfGuid(); - synchronized (description) { - description.bindString(1, guid); - return description.simpleQueryForString(); - } - } catch (SQLiteDoneException e) { - // Do nothing, it only means we have no information on the cache - } catch (Exception e) { - Log.e("cgData.getGeocodeForGuid", e); - } - - return null; - } - - public static String getCacheidForGeocode(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - init(); - - try { - final SQLiteStatement description = PreparedStatements.getCacheIdOfGeocode(); - synchronized (description) { - description.bindString(1, geocode); - return description.simpleQueryForString(); - } - } catch (SQLiteDoneException e) { - // Do nothing, it only means we have no information on the cache - } catch (Exception e) { - Log.e("cgData.getCacheidForGeocode", e); - } - - return null; - } - - /** - * Save/store a cache to the CacheCache - * - * @param cache - * the Cache to save in the CacheCache/DB - * @param saveFlags - * - * @return true = cache saved successfully to the CacheCache/DB - */ - public static boolean saveCache(Geocache cache, EnumSet saveFlags) { - if (cache == null) { - throw new IllegalArgumentException("cache must not be null"); - } - - // Merge with the data already stored in the CacheCache or in the database if - // the cache had not been loaded before, and update the CacheCache. - // Also, a DB update is required if the merge data comes from the CacheCache - // (as it may be more recent than the version in the database), or if the - // version coming from the database is different than the version we are entering - // into the cache (that includes absence from the database). - final String geocode = cache.getGeocode(); - final Geocache cacheFromCache = cacheCache.getCacheFromCache(geocode); - final boolean dbUpdateRequired = - !cache.gatherMissingFrom(cacheFromCache != null ? - cacheFromCache : - loadCache(geocode, LoadFlags.LOAD_ALL_DB_ONLY)) || - cacheFromCache != null; - cache.addStorageLocation(StorageLocation.CACHE); - cacheCache.putCacheInCache(cache); - - // Only save the cache in the database if it is requested by the caller and - // the cache contains detailed information. - if (!saveFlags.contains(SaveFlag.SAVE_DB)) { - return true; - } - - return cache.isDetailed() && dbUpdateRequired && storeIntoDatabase(cache); - } - - private static boolean storeIntoDatabase(final Geocache cache) { - cache.addStorageLocation(StorageLocation.DATABASE); - cacheCache.putCacheInCache(cache); - Log.d("Saving " + cache.toString() + " (" + cache.getListId() + ") to DB"); - - ContentValues values = new ContentValues(); - - if (cache.getUpdated() == 0) { - values.put("updated", System.currentTimeMillis()); - } else { - values.put("updated", cache.getUpdated()); - } - values.put("reason", cache.getListId()); - values.put("detailed", cache.isDetailed() ? 1 : 0); - values.put("detailedupdate", cache.getDetailedUpdate()); - values.put("visiteddate", cache.getVisitedDate()); - values.put("geocode", cache.getGeocode()); - values.put("cacheid", cache.getCacheId()); - values.put("guid", cache.getGuid()); - values.put("type", cache.getType().id); - values.put("name", cache.getName()); - values.put("owner", cache.getOwnerDisplayName()); - values.put("owner_real", cache.getOwnerUserId()); - if (cache.getHiddenDate() == null) { - values.put("hidden", 0); - } else { - values.put("hidden", cache.getHiddenDate().getTime()); - } - values.put("hint", cache.getHint()); - values.put("size", cache.getSize() == null ? "" : cache.getSize().id); - values.put("difficulty", cache.getDifficulty()); - values.put("terrain", cache.getTerrain()); - values.put("location", cache.getLocation()); - values.put("distance", cache.getDistance()); - values.put("direction", cache.getDirection()); - putCoords(values, cache.getCoords()); - values.put("reliable_latlon", cache.isReliableLatLon() ? 1 : 0); - values.put("shortdesc", cache.getShortDescription()); - values.put("personal_note", cache.getPersonalNote()); - values.put("description", cache.getDescription()); - values.put("favourite_cnt", cache.getFavoritePoints()); - values.put("rating", cache.getRating()); - values.put("votes", cache.getVotes()); - values.put("myvote", cache.getMyVote()); - values.put("disabled", cache.isDisabled() ? 1 : 0); - values.put("archived", cache.isArchived() ? 1 : 0); - values.put("members", cache.isPremiumMembersOnly() ? 1 : 0); - values.put("found", cache.isFound() ? 1 : 0); - values.put("favourite", cache.isFavorite() ? 1 : 0); - values.put("inventoryunknown", cache.getInventoryItems()); - values.put("onWatchlist", cache.isOnWatchlist() ? 1 : 0); - values.put("coordsChanged", cache.hasUserModifiedCoords() ? 1 : 0); - values.put("finalDefined", cache.hasFinalDefined() ? 1 : 0); - values.put("logPasswordRequired", cache.isLogPasswordRequired() ? 1 : 0); - - init(); - - //try to update record else insert fresh.. - database.beginTransaction(); - - try { - saveAttributesWithoutTransaction(cache); - saveOriginalWaypointsWithoutTransaction(cache); - saveSpoilersWithoutTransaction(cache); - saveLogsWithoutTransaction(cache.getGeocode(), cache.getLogs()); - saveLogCountsWithoutTransaction(cache); - saveInventoryWithoutTransaction(cache.getGeocode(), cache.getInventory()); - - int rows = database.update(dbTableCaches, values, "geocode = ?", new String[] { cache.getGeocode() }); - if (rows == 0) { - // cache is not in the DB, insert it - /* long id = */ - database.insert(dbTableCaches, null, values); - } - database.setTransactionSuccessful(); - return true; - } catch (Exception e) { - Log.e("SaveCache", e); - } finally { - database.endTransaction(); - } - - return false; - } - - private static void saveAttributesWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); - database.delete(dbTableAttributes, "geocode = ?", new String[]{geocode}); - - if (cache.getAttributes().isEmpty()) { - return; - } - SQLiteStatement statement = PreparedStatements.getInsertAttribute(); - final long timestamp = System.currentTimeMillis(); - for (String attribute : cache.getAttributes()) { - statement.bindString(1, geocode); - statement.bindLong(2, timestamp); - statement.bindString(3, attribute); - - statement.executeInsert(); - } - } - - /** - * Persists the given destination into the database. - * - * @param destination - * a destination to save - */ - public static void saveSearchedDestination(final Destination destination) { - init(); - - database.beginTransaction(); - - try { - SQLiteStatement insertDestination = PreparedStatements.getInsertSearchDestination(destination); - insertDestination.executeInsert(); - database.setTransactionSuccessful(); - } catch (Exception e) { - Log.e("Updating searchedDestinations db failed", e); - } finally { - database.endTransaction(); - } - } - - public static boolean saveWaypoints(final Geocache cache) { - init(); - database.beginTransaction(); - - try { - saveOriginalWaypointsWithoutTransaction(cache); - database.setTransactionSuccessful(); - return true; - } catch (Exception e) { - Log.e("saveWaypoints", e); - } finally { - database.endTransaction(); - } - return false; - } - - private static void saveOriginalWaypointsWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); - - List waypoints = cache.getWaypoints(); - if (CollectionUtils.isNotEmpty(waypoints)) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (Waypoint oneWaypoint : waypoints) { - if (oneWaypoint.isUserDefined()) { - continue; - } - - values.clear(); - values.put("geocode", geocode); - values.put("updated", timeStamp); - values.put("type", oneWaypoint.getWaypointType() != null ? oneWaypoint.getWaypointType().id : null); - values.put("prefix", oneWaypoint.getPrefix()); - values.put("lookup", oneWaypoint.getLookup()); - values.put("name", oneWaypoint.getName()); - values.put("latlon", oneWaypoint.getLatlon()); - putCoords(values, oneWaypoint.getCoords()); - values.put("note", oneWaypoint.getNote()); - values.put("own", oneWaypoint.isUserDefined() ? 1 : 0); - values.put("visited", oneWaypoint.isVisited() ? 1 : 0); - if (oneWaypoint.getId() < 0) { - final long rowId = database.insert(dbTableWaypoints, null, values); - oneWaypoint.setId((int) rowId); - } else { - database.update(dbTableWaypoints, values, "_id = ?", new String[] { Integer.toString(oneWaypoint.getId(), 10) }); - } - } - } - } - - /** - * Save coordinates into a ContentValues - * - * @param values - * a ContentValues to save coordinates in - * @param oneWaypoint - * coordinates to save, or null to save empty coordinates - */ - private static void putCoords(final ContentValues values, final Geopoint coords) { - values.put("latitude", coords == null ? null : coords.getLatitude()); - values.put("longitude", coords == null ? null : coords.getLongitude()); - } - - /** - * Retrieve coordinates from a Cursor - * - * @param cursor - * a Cursor representing a row in the database - * @param indexLat - * index of the latitude column - * @param indexLon - * index of the longitude column - * @return the coordinates, or null if latitude or longitude is null or the coordinates are invalid - */ - private static Geopoint getCoords(final Cursor cursor, final int indexLat, final int indexLon) { - if (cursor.isNull(indexLat) || cursor.isNull(indexLon)) { - return null; - } - - return new Geopoint(cursor.getDouble(indexLat), cursor.getDouble(indexLon)); - } - - private static boolean saveWaypointInternal(int id, String geocode, Waypoint waypoint) { - if ((StringUtils.isBlank(geocode) && id <= 0) || waypoint == null) { - return false; - } - - init(); - - database.beginTransaction(); - boolean ok = false; - try { - ContentValues values = new ContentValues(); - values.put("geocode", geocode); - values.put("updated", System.currentTimeMillis()); - values.put("type", waypoint.getWaypointType() != null ? waypoint.getWaypointType().id : null); - values.put("prefix", waypoint.getPrefix()); - values.put("lookup", waypoint.getLookup()); - values.put("name", waypoint.getName()); - values.put("latlon", waypoint.getLatlon()); - putCoords(values, waypoint.getCoords()); - values.put("note", waypoint.getNote()); - values.put("own", waypoint.isUserDefined() ? 1 : 0); - values.put("visited", waypoint.isVisited() ? 1 : 0); - if (id <= 0) { - final long rowId = database.insert(dbTableWaypoints, null, values); - waypoint.setId((int) rowId); - ok = true; - } else { - final int rows = database.update(dbTableWaypoints, values, "_id = " + id, null); - ok = rows > 0; - } - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - - return ok; - } - - public static boolean deleteWaypoint(int id) { - if (id == 0) { - return false; - } - - init(); - - return database.delete(dbTableWaypoints, "_id = " + id, null) > 0; - } - - private static void saveSpoilersWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); - database.delete(dbTableSpoilers, "geocode = ?", new String[]{geocode}); - - List spoilers = cache.getSpoilers(); - if (CollectionUtils.isNotEmpty(spoilers)) { - SQLiteStatement insertSpoiler = PreparedStatements.getInsertSpoiler(); - final long timestamp = System.currentTimeMillis(); - for (Image spoiler : spoilers) { - insertSpoiler.bindString(1, geocode); - insertSpoiler.bindLong(2, timestamp); - insertSpoiler.bindString(3, spoiler.getUrl()); - insertSpoiler.bindString(4, spoiler.getTitle()); - final String description = spoiler.getDescription(); - if (description != null) { - insertSpoiler.bindString(5, description); - } - else { - insertSpoiler.bindNull(5); - } - insertSpoiler.executeInsert(); - } - } - } - - private static void saveLogsWithoutTransaction(final String geocode, final Iterable logs) { - // TODO delete logimages referring these logs - database.delete(dbTableLogs, "geocode = ?", new String[]{geocode}); - - if (!logs.iterator().hasNext()) { - return; - } - - SQLiteStatement insertLog = PreparedStatements.getInsertLog(); - final long timestamp = System.currentTimeMillis(); - for (LogEntry log : logs) { - insertLog.bindString(1, geocode); - insertLog.bindLong(2, timestamp); - insertLog.bindLong(3, log.type.id); - insertLog.bindString(4, log.author); - insertLog.bindString(5, log.log); - insertLog.bindLong(6, log.date); - insertLog.bindLong(7, log.found); - insertLog.bindLong(8, log.friend ? 1 : 0); - long logId = insertLog.executeInsert(); - if (log.hasLogImages()) { - SQLiteStatement insertImage = PreparedStatements.getInsertLogImage(); - for (Image img : log.getLogImages()) { - insertImage.bindLong(1, logId); - insertImage.bindString(2, img.getTitle()); - insertImage.bindString(3, img.getUrl()); - insertImage.executeInsert(); - } - } - } - } - - private static void saveLogCountsWithoutTransaction(final Geocache cache) { - String geocode = cache.getGeocode(); - database.delete(dbTableLogCount, "geocode = ?", new String[]{geocode}); - - Map logCounts = cache.getLogCounts(); - if (MapUtils.isNotEmpty(logCounts)) { - Set> logCountsItems = logCounts.entrySet(); - SQLiteStatement insertLogCounts = PreparedStatements.getInsertLogCounts(); - final long timestamp = System.currentTimeMillis(); - for (Entry pair : logCountsItems) { - insertLogCounts.bindString(1, geocode); - insertLogCounts.bindLong(2, timestamp); - insertLogCounts.bindLong(3, pair.getKey().id); - insertLogCounts.bindLong(4, pair.getValue()); - - insertLogCounts.executeInsert(); - } - } - } - - public static void saveTrackable(final Trackable trackable) { - init(); - - database.beginTransaction(); - try { - saveInventoryWithoutTransaction(null, Collections.singletonList(trackable)); - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - } - - private static void saveInventoryWithoutTransaction(final String geocode, final List trackables) { - if (geocode != null) { - database.delete(dbTableTrackables, "geocode = ?", new String[]{geocode}); - } - - if (CollectionUtils.isNotEmpty(trackables)) { - ContentValues values = new ContentValues(); - long timeStamp = System.currentTimeMillis(); - for (Trackable trackable : trackables) { - final String tbCode = trackable.getGeocode(); - if (StringUtils.isNotBlank(tbCode)) { - database.delete(dbTableTrackables, "tbcode = ?", new String[] { tbCode }); - } - values.clear(); - if (geocode != null) { - values.put("geocode", geocode); - } - values.put("updated", timeStamp); - values.put("tbcode", tbCode); - values.put("guid", trackable.getGuid()); - values.put("title", trackable.getName()); - values.put("owner", trackable.getOwner()); - if (trackable.getReleased() != null) { - values.put("released", trackable.getReleased().getTime()); - } else { - values.put("released", 0L); - } - values.put("goal", trackable.getGoal()); - values.put("description", trackable.getDetails()); - - database.insert(dbTableTrackables, null, values); - - saveLogsWithoutTransaction(tbCode, trackable.getLogs()); - } - } - } - - public static Viewport getBounds(final Set geocodes) { - if (CollectionUtils.isEmpty(geocodes)) { - return null; - } - - final Set caches = loadCaches(geocodes, LoadFlags.LOAD_CACHE_OR_DB); - return Viewport.containing(caches); - } - - /** - * Load a single Cache. - * - * @param geocode - * The Geocode GCXXXX - * @return the loaded cache (if found). Can be null - */ - public static Geocache loadCache(final String geocode, final EnumSet loadFlags) { - if (StringUtils.isBlank(geocode)) { - throw new IllegalArgumentException("geocode must not be empty"); - } - - final Set caches = loadCaches(Collections.singleton(geocode), loadFlags); - return caches.isEmpty() ? null : caches.iterator().next(); - } - - /** - * Load caches. - * - * @param geocodes - * @return Set of loaded caches. Never null. - */ - public static Set loadCaches(final Collection geocodes, final EnumSet loadFlags) { - if (CollectionUtils.isEmpty(geocodes)) { - return new HashSet(); - } - - Set result = new HashSet(); - Set remaining = new HashSet(geocodes); - - if (loadFlags.contains(LoadFlag.LOAD_CACHE_BEFORE)) { - for (String geocode : new HashSet(remaining)) { - Geocache cache = cacheCache.getCacheFromCache(geocode); - if (cache != null) { - result.add(cache); - remaining.remove(cache.getGeocode()); - } - } - } - - if (loadFlags.contains(LoadFlag.LOAD_DB_MINIMAL) || - loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES) || - loadFlags.contains(LoadFlag.LOAD_WAYPOINTS) || - loadFlags.contains(LoadFlag.LOAD_SPOILERS) || - loadFlags.contains(LoadFlag.LOAD_LOGS) || - loadFlags.contains(LoadFlag.LOAD_INVENTORY) || - loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { - - final Set cachesFromDB = loadCachesFromGeocodes(remaining, loadFlags); - result.addAll(cachesFromDB); - for (final Geocache cache : cachesFromDB) { - remaining.remove(cache.getGeocode()); - } - } - - if (loadFlags.contains(LoadFlag.LOAD_CACHE_AFTER)) { - for (String geocode : new HashSet(remaining)) { - Geocache cache = cacheCache.getCacheFromCache(geocode); - if (cache != null) { - result.add(cache); - remaining.remove(cache.getGeocode()); - } - } - } - - if (remaining.size() >= 1) { - Log.d("cgData.loadCaches(" + remaining.toString() + ") returned no results"); - } - return result; - } - - /** - * Load caches. - * - * @param geocodes - * @param loadFlags - * @return Set of loaded caches. Never null. - */ - private static Set loadCachesFromGeocodes(final Set geocodes, final EnumSet loadFlags) { - if (CollectionUtils.isEmpty(geocodes)) { - return Collections.emptySet(); - } - - // do not log the entire collection of geo codes to the debug log. This can be more than 100 KB of text for large lists! - init(); - - final StringBuilder query = new StringBuilder(QUERY_CACHE_DATA); - if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { - query.append(',').append(dbTableLogsOffline).append(".log"); - } - - query.append(" FROM ").append(dbTableCaches); - if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { - query.append(" LEFT OUTER JOIN ").append(dbTableLogsOffline).append(" ON ( ").append(dbTableCaches).append(".geocode == ").append(dbTableLogsOffline).append(".geocode) "); - } - - query.append(" WHERE ").append(dbTableCaches).append('.'); - query.append(cgData.whereGeocodeIn(geocodes)); - - Cursor cursor = database.rawQuery(query.toString(), null); - try { - final Set caches = new HashSet(); - int logIndex = -1; - - while (cursor.moveToNext()) { - Geocache cache = cgData.createCacheFromDatabaseContent(cursor); - - if (loadFlags.contains(LoadFlag.LOAD_ATTRIBUTES)) { - cache.setAttributes(loadAttributes(cache.getGeocode())); - } - - if (loadFlags.contains(LoadFlag.LOAD_WAYPOINTS)) { - final List waypoints = loadWaypoints(cache.getGeocode()); - if (CollectionUtils.isNotEmpty(waypoints)) { - cache.setWaypoints(waypoints, false); - } - } - - if (loadFlags.contains(LoadFlag.LOAD_SPOILERS)) { - final List spoilers = loadSpoilers(cache.getGeocode()); - cache.setSpoilers(spoilers); - } - - if (loadFlags.contains(LoadFlag.LOAD_LOGS)) { - cache.setLogs(loadLogs(cache.getGeocode())); - final Map logCounts = loadLogCounts(cache.getGeocode()); - if (MapUtils.isNotEmpty(logCounts)) { - cache.getLogCounts().clear(); - cache.getLogCounts().putAll(logCounts); - } - } - - if (loadFlags.contains(LoadFlag.LOAD_INVENTORY)) { - final List inventory = loadInventory(cache.getGeocode()); - if (CollectionUtils.isNotEmpty(inventory)) { - if (cache.getInventory() == null) { - cache.setInventory(new ArrayList()); - } else { - cache.getInventory().clear(); - } - cache.getInventory().addAll(inventory); - } - } - - if (loadFlags.contains(LoadFlag.LOAD_OFFLINE_LOG)) { - if (logIndex < 0) { - logIndex = cursor.getColumnIndex("log"); - } - cache.setLogOffline(!cursor.isNull(logIndex)); - } - cache.addStorageLocation(StorageLocation.DATABASE); - cacheCache.putCacheInCache(cache); - - caches.add(cache); - } - return caches; - } finally { - cursor.close(); - } - } - - - /** - * Builds a where for a viewport with the size enhanced by 50%. - * - * @param dbTable - * @param viewport - * @return - */ - - private static String buildCoordinateWhere(final String dbTable, final Viewport viewport) { - return viewport.resize(1.5).sqlWhere(dbTable); - } - - /** - * creates a Cache from the cursor. Doesn't next. - * - * @param cursor - * @return Cache from DB - */ - private static Geocache createCacheFromDatabaseContent(Cursor cursor) { - Geocache cache = new Geocache(); - - cache.setUpdated(cursor.getLong(0)); - cache.setListId(cursor.getInt(1)); - cache.setDetailed(cursor.getInt(2) == 1); - cache.setDetailedUpdate(cursor.getLong(3)); - cache.setVisitedDate(cursor.getLong(4)); - cache.setGeocode(cursor.getString(5)); - cache.setCacheId(cursor.getString(6)); - cache.setGuid(cursor.getString(7)); - cache.setType(CacheType.getById(cursor.getString(8))); - cache.setName(cursor.getString(9)); - cache.setOwnerDisplayName(cursor.getString(10)); - cache.setOwnerUserId(cursor.getString(11)); - long dateValue = cursor.getLong(12); - if (dateValue != 0) { - cache.setHidden(new Date(dateValue)); - } - // do not set cache.hint - cache.setSize(CacheSize.getById(cursor.getString(14))); - cache.setDifficulty(cursor.getFloat(15)); - int index = 16; - if (cursor.isNull(index)) { - cache.setDirection(null); - } else { - cache.setDirection(cursor.getFloat(index)); - } - index = 17; - if (cursor.isNull(index)) { - cache.setDistance(null); - } else { - cache.setDistance(cursor.getFloat(index)); - } - cache.setTerrain(cursor.getFloat(18)); - // do not set cache.location - cache.setCoords(getCoords(cursor, 36, 37)); - cache.setPersonalNote(cursor.getString(21)); - // do not set cache.shortdesc - // do not set cache.description - cache.setFavoritePoints(cursor.getInt(23)); - cache.setRating(cursor.getFloat(24)); - cache.setVotes(cursor.getInt(25)); - cache.setMyVote(cursor.getFloat(26)); - cache.setDisabled(cursor.getInt(27) == 1); - cache.setArchived(cursor.getInt(28) == 1); - cache.setPremiumMembersOnly(cursor.getInt(29) == 1); - cache.setFound(cursor.getInt(30) == 1); - cache.setFavorite(cursor.getInt(31) == 1); - cache.setInventoryItems(cursor.getInt(32)); - cache.setOnWatchlist(cursor.getInt(33) == 1); - cache.setReliableLatLon(cursor.getInt(34) > 0); - cache.setUserModifiedCoords(cursor.getInt(35) > 0); - cache.setFinalDefined(cursor.getInt(38) > 0); - cache.setLogPasswordRequired(cursor.getInt(42) > 0); - - Log.d("Loading " + cache.toString() + " (" + cache.getListId() + ") from DB"); - - return cache; - } - - public static List loadAttributes(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final ArrayList attributes = new ArrayList(); - - final Cursor cursor = database.query( - dbTableAttributes, - new String[]{"attribute"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - null, - "100"); - - while (cursor.moveToNext()) { - attributes.add(cursor.getString(0)); - } - - cursor.close(); - - return attributes; - } - - public static Waypoint loadWaypoint(int id) { - if (id == 0) { - return null; - } - - init(); - - final Cursor cursor = database.query( - dbTableWaypoints, - WAYPOINT_COLUMNS, - "_id = ?", - new String[]{Integer.toString(id)}, - null, - null, - null, - "1"); - - Log.d("cgData.loadWaypoint(" + id + ")"); - - final Waypoint waypoint = cursor.moveToFirst() ? createWaypointFromDatabaseContent(cursor) : null; - - cursor.close(); - - return waypoint; - } - - public static List loadWaypoints(final String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final List waypoints = new ArrayList(); - - final Cursor cursor = database.query( - dbTableWaypoints, - WAYPOINT_COLUMNS, - "geocode = ?", - new String[]{geocode}, - null, - null, - "_id", - "100"); - - while (cursor.moveToNext()) { - waypoints.add(createWaypointFromDatabaseContent(cursor)); - } - - cursor.close(); - - return waypoints; - } - - private static Waypoint createWaypointFromDatabaseContent(final Cursor cursor) { - final String name = cursor.getString(cursor.getColumnIndex("name")); - final WaypointType type = WaypointType.findById(cursor.getString(cursor.getColumnIndex("type"))); - final boolean own = cursor.getInt(cursor.getColumnIndex("own")) != 0; - final Waypoint waypoint = new Waypoint(name, type, own); - waypoint.setVisited(cursor.getInt(cursor.getColumnIndex("visited")) != 0); - waypoint.setId(cursor.getInt(cursor.getColumnIndex("_id"))); - waypoint.setGeocode(cursor.getString(cursor.getColumnIndex("geocode"))); - waypoint.setPrefix(cursor.getString(cursor.getColumnIndex("prefix"))); - waypoint.setLookup(cursor.getString(cursor.getColumnIndex("lookup"))); - waypoint.setLatlon(cursor.getString(cursor.getColumnIndex("latlon"))); - waypoint.setCoords(getCoords(cursor, cursor.getColumnIndex("latitude"), cursor.getColumnIndex("longitude"))); - waypoint.setNote(cursor.getString(cursor.getColumnIndex("note"))); - - return waypoint; - } - - private static List loadSpoilers(final String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final List spoilers = new ArrayList(); - - final Cursor cursor = database.query( - dbTableSpoilers, - new String[]{"url", "title", "description"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - null, - "100"); - - while (cursor.moveToNext()) { - spoilers.add(new Image(cursor.getString(0), cursor.getString(1), cursor.getString(2))); - } - - cursor.close(); - - return spoilers; - } - - /** - * Loads the history of previously entered destinations from - * the database. If no destinations exist, an {@link Collections#emptyList()} will be returned. - * - * @return A list of previously entered destinations or an empty list. - */ - public static List loadHistoryOfSearchedLocations() { - init(); - - final Cursor cursor = database.query(dbTableSearchDestionationHistory, - new String[]{"_id", "date", "latitude", "longitude"}, - null, - null, - null, - null, - "date desc", - "100"); - - final List destinations = new LinkedList(); - - while (cursor.moveToNext()) { - final Destination dest = new Destination(cursor.getLong(0), cursor.getLong(1), getCoords(cursor, 2, 3)); - - // If coordinates are non-existent or invalid, do not consider this point. - if (dest.getCoords() != null) { - destinations.add(dest); - } - } - - cursor.close(); - - return destinations; - } - - public static boolean clearSearchedDestinations() { - init(); - database.beginTransaction(); - - try { - database.delete(dbTableSearchDestionationHistory, null, null); - database.setTransactionSuccessful(); - return true; - } catch (Exception e) { - Log.e("Unable to clear searched destinations", e); - } finally { - database.endTransaction(); - } - - return false; - } - - public static List loadLogs(String geocode) { - List logs = new ArrayList(); - - if (StringUtils.isBlank(geocode)) { - return logs; - } - - init(); - - final Cursor cursor = database.rawQuery( - /* 0 1 2 3 4 5 6 7 8 9 10 */ - "SELECT cg_logs._id as cg_logs_id, type, author, log, date, found, friend, " + dbTableLogImages + "._id as cg_logImages_id, log_id, title, url" - + " FROM " + dbTableLogs + " LEFT OUTER JOIN " + dbTableLogImages - + " ON ( cg_logs._id = log_id ) WHERE geocode = ? ORDER BY date desc, cg_logs._id asc", new String[]{geocode}); - - LogEntry log = null; - while (cursor.moveToNext() && logs.size() < 100) { - if (log == null || log.id != cursor.getInt(0)) { - log = new LogEntry( - cursor.getString(2), - cursor.getLong(4), - LogType.getById(cursor.getInt(1)), - cursor.getString(3)); - log.id = cursor.getInt(0); - log.found = cursor.getInt(5); - log.friend = cursor.getInt(6) == 1; - logs.add(log); - } - if (!cursor.isNull(7)) { - log.addLogImage(new Image(cursor.getString(10), cursor.getString(9))); - } - } - - cursor.close(); - - return logs; - } - - public static Map loadLogCounts(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final Map logCounts = new HashMap(); - - final Cursor cursor = database.query( - dbTableLogCount, - new String[]{"type", "count"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - null, - "100"); - - while (cursor.moveToNext()) { - logCounts.put(LogType.getById(cursor.getInt(0)), cursor.getInt(1)); - } - - cursor.close(); - - return logCounts; - } - - private static List loadInventory(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final List trackables = new ArrayList(); - - final Cursor cursor = database.query( - dbTableTrackables, - new String[]{"_id", "updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - "title COLLATE NOCASE ASC", - "100"); - - while (cursor.moveToNext()) { - trackables.add(createTrackableFromDatabaseContent(cursor)); - } - - cursor.close(); - - return trackables; - } - - public static Trackable loadTrackable(final String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - final Cursor cursor = database.query( - dbTableTrackables, - new String[]{"updated", "tbcode", "guid", "title", "owner", "released", "goal", "description"}, - "tbcode = ?", - new String[]{geocode}, - null, - null, - null, - "1"); - - final Trackable trackable = cursor.moveToFirst() ? createTrackableFromDatabaseContent(cursor) : null; - - cursor.close(); - - return trackable; - } - - private static Trackable createTrackableFromDatabaseContent(final Cursor cursor) { - final Trackable trackable = new Trackable(); - trackable.setGeocode(cursor.getString(cursor.getColumnIndex("tbcode"))); - trackable.setGuid(cursor.getString(cursor.getColumnIndex("guid"))); - trackable.setName(cursor.getString(cursor.getColumnIndex("title"))); - trackable.setOwner(cursor.getString(cursor.getColumnIndex("owner"))); - final String released = cursor.getString(cursor.getColumnIndex("released")); - if (released != null) { - try { - long releaseMilliSeconds = Long.parseLong(released); - trackable.setReleased(new Date(releaseMilliSeconds)); - } catch (final NumberFormatException e) { - Log.e("createTrackableFromDatabaseContent", e); - } - } - trackable.setGoal(cursor.getString(cursor.getColumnIndex("goal"))); - trackable.setDetails(cursor.getString(cursor.getColumnIndex("description"))); - trackable.setLogs(loadLogs(trackable.getGeocode())); - return trackable; - } - - /** - * Number of caches stored for a given type and/or list - * - * @param cacheType - * @param list - * @return - */ - public static int getAllStoredCachesCount(final CacheType cacheType, final int list) { - if (cacheType == null) { - throw new IllegalArgumentException("cacheType must not be null"); - } - if (list <= 0) { - throw new IllegalArgumentException("list must be > 0"); - } - init(); - - try { - StringBuilder sql = new StringBuilder("select count(_id) from " + dbTableCaches + " where detailed = 1"); - String typeKey; - int reasonIndex; - if (cacheType != CacheType.ALL) { - sql.append(" and type = ?"); - typeKey = cacheType.id; - reasonIndex = 2; - } - else { - typeKey = "all_types"; - reasonIndex = 1; - } - String listKey; - if (list == StoredList.ALL_LIST_ID) { - sql.append(" and reason > 0"); - listKey = "all_list"; - } else { - sql.append(" and reason = ?"); - listKey = "list"; - } - - String key = "CountCaches_" + typeKey + "_" + listKey; - - SQLiteStatement compiledStmnt = PreparedStatements.getStatement(key, sql.toString()); - if (cacheType != CacheType.ALL) { - compiledStmnt.bindString(1, cacheType.id); - } - if (list != StoredList.ALL_LIST_ID) { - compiledStmnt.bindLong(reasonIndex, list); - } - return (int) compiledStmnt.simpleQueryForLong(); - } catch (Exception e) { - Log.e("cgData.loadAllStoredCachesCount", e); - } - - return 0; - } - - public static int getAllHistoryCachesCount() { - init(); - - try { - return (int) PreparedStatements.getCountHistoryCaches().simpleQueryForLong(); - } catch (Exception e) { - Log.e("cgData.getAllHistoricCachesCount", e); - } - - return 0; - } - - /** - * Return a batch of stored geocodes. - * - * @param coords - * the current coordinates to sort by distance, or null to sort by geocode - * @param cacheType - * @param listId - * @return a non-null set of geocodes - */ - private static Set loadBatchOfStoredGeocodes(final Geopoint coords, final CacheType cacheType, final int listId) { - if (cacheType == null) { - throw new IllegalArgumentException("cacheType must not be null"); - } - init(); - - final Set geocodes = new HashSet(); - - final StringBuilder selection = new StringBuilder(); - - selection.append("reason "); - selection.append(listId != StoredList.ALL_LIST_ID ? "=" + Math.max(listId, 1) : ">= " + StoredList.STANDARD_LIST_ID); - selection.append(" and detailed = 1 "); - - String[] selectionArgs = null; - if (cacheType != CacheType.ALL) { - selection.append(" and type = ?"); - selectionArgs = new String[] { String.valueOf(cacheType.id) }; - } - - try { - Cursor cursor; - if (coords != null) { - cursor = database.query( - dbTableCaches, - new String[]{"geocode", "(abs(latitude-" + String.format((Locale) null, "%.6f", coords.getLatitude()) + - ") + abs(longitude-" + String.format((Locale) null, "%.6f", coords.getLongitude()) + ")) as dif"}, - selection.toString(), - selectionArgs, - null, - null, - "dif", - null); - } else { - cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - selection.toString(), - selectionArgs, - null, - null, - "geocode"); - } - - while (cursor.moveToNext()) { - geocodes.add(cursor.getString(0)); - } - - cursor.close(); - } catch (final Exception e) { - Log.e("cgData.loadBatchOfStoredGeocodes", e); - } - - return geocodes; - } - - private static Set loadBatchOfHistoricGeocodes(final boolean detailedOnly, final CacheType cacheType) { - init(); - - final Set geocodes = new HashSet(); - - final StringBuilder selection = new StringBuilder("visiteddate > 0"); - - if (detailedOnly) { - selection.append(" and detailed = 1"); - } - String[] selectionArgs = null; - if (cacheType != CacheType.ALL) { - selection.append(" and type = ?"); - selectionArgs = new String[] { String.valueOf(cacheType.id) }; - } - - try { - final Cursor cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - selection.toString(), - selectionArgs, - null, - null, - "visiteddate", - null); - while (cursor.moveToNext()) { - geocodes.add(cursor.getString(0)); - } - cursor.close(); - } catch (Exception e) { - Log.e("cgData.loadBatchOfHistoricGeocodes", e); - } - - return geocodes; - } - - /** Retrieve all stored caches from DB */ - public static SearchResult loadCachedInViewport(final Viewport viewport, final CacheType cacheType) { - return loadInViewport(false, viewport, cacheType); - } - - /** Retrieve stored caches from DB with listId >= 1 */ - public static SearchResult loadStoredInViewport(final Viewport viewport, final CacheType cacheType) { - return loadInViewport(true, viewport, cacheType); - } - - /** - * Loads the geocodes of caches in a viewport from CacheCache and/or Database - * - * @param stored - * True - query only stored caches, False - query cached ones as well - * @param centerLat - * @param centerLon - * @param spanLat - * @param spanLon - * @param cacheType - * @return Set with geocodes - */ - private static SearchResult loadInViewport(final boolean stored, final Viewport viewport, final CacheType cacheType) { - init(); - - final Set geocodes = new HashSet(); - - // if not stored only, get codes from CacheCache as well - if (!stored) { - geocodes.addAll(cacheCache.getInViewport(viewport, cacheType)); - } - - // viewport limitation - final StringBuilder selection = new StringBuilder(buildCoordinateWhere(dbTableCaches, viewport)); - - // cacheType limitation - String[] selectionArgs = null; - if (cacheType != CacheType.ALL) { - selection.append(" and type = ?"); - selectionArgs = new String[] { String.valueOf(cacheType.id) }; - } - - // offline caches only - if (stored) { - selection.append(" and reason >= " + StoredList.STANDARD_LIST_ID); - } - - try { - final Cursor cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - selection.toString(), - selectionArgs, - null, - null, - null, - "500"); - - while (cursor.moveToNext()) { - geocodes.add(cursor.getString(0)); - } - - cursor.close(); - } catch (final Exception e) { - Log.e("cgData.loadInViewport", e); - } - - return new SearchResult(geocodes); - } - - /** delete caches from the DB store 3 days or more before */ - public static void clean() { - clean(false); - } - - /** - * Remove caches with listId = 0 - * - * @param more - * true = all caches false = caches stored 3 days or more before - */ - public static void clean(final boolean more) { - if (databaseCleaned) { - return; - } - - init(); - - Log.d("Database clean: started"); - - try { - Cursor cursor; - if (more) { - cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - "reason = 0", - null, - null, - null, - null, - null); - } else { - long timestamp = System.currentTimeMillis() - DAYS_AFTER_CACHE_IS_DELETED; - String timestampString = Long.toString(timestamp); - cursor = database.query( - dbTableCaches, - new String[]{"geocode"}, - "reason = 0 and detailed < ? and detailedupdate < ? and visiteddate < ?", - new String[]{timestampString, timestampString, timestampString}, - null, - null, - null, - null); - } - - Set geocodes = new HashSet(); - while (cursor.moveToNext()) { - geocodes.add(cursor.getString(0)); - } - - cursor.close(); - - if (!geocodes.isEmpty()) { - Log.d("Database clean: removing " + geocodes.size() + " geocaches from listId=0"); - removeCaches(geocodes, LoadFlags.REMOVE_ALL); - } - } catch (final Exception e) { - Log.w("cgData.clean", e); - } - - Log.d("Database clean: finished"); - databaseCleaned = true; - } - - public static void removeAllFromCache() { - // clean up CacheCache - cacheCache.removeAllFromCache(); - } - - public static void removeCache(final String geocode, EnumSet removeFlags) { - removeCaches(Collections.singleton(geocode), removeFlags); - } - - /** - * Drop caches from the tables they are stored into, as well as the cache files - * - * @param geocodes - * list of geocodes to drop from cache - */ - public static void removeCaches(final Set geocodes, EnumSet removeFlags) { - if (CollectionUtils.isEmpty(geocodes)) { - return; - } - - init(); - - if (removeFlags.contains(RemoveFlag.REMOVE_CACHE)) { - for (final String geocode : geocodes) { - cacheCache.removeCacheFromCache(geocode); - } - } - - if (removeFlags.contains(RemoveFlag.REMOVE_DB)) { - // Drop caches from the database - final ArrayList quotedGeocodes = new ArrayList(geocodes.size()); - for (final String geocode : geocodes) { - quotedGeocodes.add(DatabaseUtils.sqlEscapeString(geocode)); - } - final String geocodeList = StringUtils.join(quotedGeocodes.toArray(), ','); - final String baseWhereClause = "geocode in (" + geocodeList + ")"; - database.beginTransaction(); - try { - database.delete(dbTableCaches, baseWhereClause, null); - database.delete(dbTableAttributes, baseWhereClause, null); - database.delete(dbTableSpoilers, baseWhereClause, null); - database.delete(dbTableLogs, baseWhereClause, null); - database.delete(dbTableLogCount, baseWhereClause, null); - database.delete(dbTableLogsOffline, baseWhereClause, null); - String wayPointClause = baseWhereClause; - if (!removeFlags.contains(RemoveFlag.REMOVE_OWN_WAYPOINTS_ONLY_FOR_TESTING)) { - wayPointClause += " and type <> 'own'"; - } - database.delete(dbTableWaypoints, wayPointClause, null); - database.delete(dbTableTrackables, baseWhereClause, null); - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - - // Delete cache directories - for (final String geocode : geocodes) { - LocalStorage.deleteDirectory(LocalStorage.getStorageDir(geocode)); - } - } - } - - public static boolean saveLogOffline(String geocode, Date date, LogType type, String log) { - if (StringUtils.isBlank(geocode)) { - Log.e("cgData.saveLogOffline: cannot log a blank geocode"); - return false; - } - if (LogType.UNKNOWN == type && StringUtils.isBlank(log)) { - Log.e("cgData.saveLogOffline: cannot log an unknown log type and no message"); - return false; - } - - init(); - - final ContentValues values = new ContentValues(); - values.put("geocode", geocode); - values.put("updated", System.currentTimeMillis()); - values.put("type", type.id); - values.put("log", log); - values.put("date", date.getTime()); - - if (hasLogOffline(geocode)) { - final int rows = database.update(dbTableLogsOffline, values, "geocode = ?", new String[] { geocode }); - return rows > 0; - } - final long id = database.insert(dbTableLogsOffline, null, values); - return id != -1; - } - - public static LogEntry loadLogOffline(String geocode) { - if (StringUtils.isBlank(geocode)) { - return null; - } - - init(); - - - final Cursor cursor = database.query( - dbTableLogsOffline, - new String[]{"_id", "type", "log", "date"}, - "geocode = ?", - new String[]{geocode}, - null, - null, - "_id desc", - "1"); - - LogEntry log = null; - if (cursor.moveToFirst()) { - log = new LogEntry(cursor.getLong(3), - LogType.getById(cursor.getInt(1)), - cursor.getString(2)); - log.id = cursor.getInt(0); - } - - cursor.close(); - - return log; - } - - public static void clearLogOffline(String geocode) { - if (StringUtils.isBlank(geocode)) { - return; - } - - init(); - - database.delete(dbTableLogsOffline, "geocode = ?", new String[]{geocode}); - } - - public static void clearLogsOffline(List caches) { - if (CollectionUtils.isEmpty(caches)) { - return; - } - - init(); - - Set geocodes = new HashSet(caches.size()); - for (Geocache cache : caches) { - geocodes.add(cache.getGeocode()); - cache.setLogOffline(false); - } - - database.execSQL(String.format("DELETE FROM %s where %s", dbTableLogsOffline, whereGeocodeIn(geocodes))); - } - - public static boolean hasLogOffline(final String geocode) { - if (StringUtils.isBlank(geocode)) { - return false; - } - - init(); - try { - final SQLiteStatement logCount = PreparedStatements.getLogCountOfGeocode(); - synchronized (logCount) { - logCount.bindString(1, geocode); - return logCount.simpleQueryForLong() > 0; - } - } catch (Exception e) { - Log.e("cgData.hasLogOffline", e); - } - - return false; - } - - private static void setVisitDate(List geocodes, long visitedDate) { - if (geocodes.isEmpty()) { - return; - } - - init(); - - database.beginTransaction(); - try { - SQLiteStatement setVisit = PreparedStatements.getUpdateVisitDate(); - - for (String geocode : geocodes) { - setVisit.bindLong(1, visitedDate); - setVisit.bindString(2, geocode); - setVisit.execute(); - } - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - } - - @NonNull - public static List getLists() { - init(); - - final Resources res = cgeoapplication.getInstance().getResources(); - final List lists = new ArrayList(); - lists.add(new StoredList(StoredList.STANDARD_LIST_ID, res.getString(R.string.list_inbox), (int) PreparedStatements.getCountCachesOnStandardList().simpleQueryForLong())); - - try { - String query = "SELECT l._id as _id, l.title as title, COUNT(c._id) as count" + - " FROM " + dbTableLists + " l LEFT OUTER JOIN " + dbTableCaches + " c" + - " ON l._id + " + customListIdOffset + " = c.reason" + - " GROUP BY l._id" + - " ORDER BY l.title COLLATE NOCASE ASC"; - - final Cursor cursor = database.rawQuery(query, null); - ArrayList storedLists = getListsFromCursor(cursor); - lists.addAll(storedLists); - cursor.close(); - } catch (final Exception e) { - Log.e("cgData.readLists", e); - } - return lists; - } - - private static ArrayList getListsFromCursor(final Cursor cursor) { - final int indexId = cursor.getColumnIndex("_id"); - final int indexTitle = cursor.getColumnIndex("title"); - final int indexCount = cursor.getColumnIndex("count"); - final ArrayList result = new ArrayList(); - while (cursor.moveToNext()) { - final int count = indexCount != -1 ? cursor.getInt(indexCount) : 0; - final StoredList list = new StoredList(cursor.getInt(indexId) + customListIdOffset, cursor.getString(indexTitle), count); - result.add(list); - } - cursor.close(); - return result; - } - - public static StoredList getList(int id) { - init(); - if (id >= customListIdOffset) { - Cursor cursor = database.query( - dbTableLists, - new String[]{"_id", "title"}, - "_id = ? ", - new String[] { String.valueOf(id - customListIdOffset) }, - null, - null, - null); - ArrayList lists = getListsFromCursor(cursor); - if (!lists.isEmpty()) { - return lists.get(0); - } - } - - Resources res = cgeoapplication.getInstance().getResources(); - if (id == StoredList.ALL_LIST_ID) { - return new StoredList(StoredList.ALL_LIST_ID, res.getString(R.string.list_all_lists), getAllCachesCount()); - } - - // fall back to standard list in case of invalid list id - if (id == StoredList.STANDARD_LIST_ID || id >= customListIdOffset) { - return new StoredList(StoredList.STANDARD_LIST_ID, res.getString(R.string.list_inbox), (int) PreparedStatements.getCountCachesOnStandardList().simpleQueryForLong()); - } - - return null; - } - - public static int getAllCachesCount() { - return (int) PreparedStatements.getCountAllCaches().simpleQueryForLong(); - } - - /** - * Create a new list - * - * @param name - * Name - * @return new listId - */ - public static int createList(String name) { - int id = -1; - if (StringUtils.isBlank(name)) { - return id; - } - - init(); - - database.beginTransaction(); - try { - ContentValues values = new ContentValues(); - values.put("title", name); - values.put("updated", System.currentTimeMillis()); - - id = (int) database.insert(dbTableLists, null, values); - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - - return id >= 0 ? id + customListIdOffset : -1; - } - - /** - * @param listId - * List to change - * @param name - * New name of list - * @return Number of lists changed - */ - public static int renameList(final int listId, final String name) { - if (StringUtils.isBlank(name) || StoredList.STANDARD_LIST_ID == listId) { - return 0; - } - - init(); - - database.beginTransaction(); - int count = 0; - try { - ContentValues values = new ContentValues(); - values.put("title", name); - values.put("updated", System.currentTimeMillis()); - - count = database.update(dbTableLists, values, "_id = " + (listId - customListIdOffset), null); - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - - return count; - } - - /** - * Remove a list. Caches in the list are moved to the standard list. - * - * @param listId - * @return true if the list got deleted, false else - */ - public static boolean removeList(int listId) { - if (listId < customListIdOffset) { - return false; - } - - init(); - - database.beginTransaction(); - boolean status = false; - try { - int cnt = database.delete(dbTableLists, "_id = " + (listId - customListIdOffset), null); - - if (cnt > 0) { - // move caches from deleted list to standard list - SQLiteStatement moveToStandard = PreparedStatements.getMoveToStandardList(); - moveToStandard.bindLong(1, listId); - moveToStandard.execute(); - - status = true; - } - - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - - return status; - } - - public static void moveToList(final Geocache cache, final int listId) { - moveToList(Collections.singletonList(cache), listId); - } - - public static void moveToList(final List caches, final int listId) { - if (listId == StoredList.ALL_LIST_ID) { - return; - } - if (caches.isEmpty()) { - return; - } - init(); - - SQLiteStatement move = PreparedStatements.getMoveToList(); - - database.beginTransaction(); - try { - for (Geocache cache : caches) { - move.bindLong(1, listId); - move.bindString(2, cache.getGeocode()); - move.execute(); - cache.setListId(listId); - } - database.setTransactionSuccessful(); - } finally { - database.endTransaction(); - } - } - - public static boolean isInitialized() { - return database != null; - } - - public static boolean removeSearchedDestination(Destination destination) { - if (destination == null) { - return false; - } - init(); - - database.beginTransaction(); - try { - database.delete(dbTableSearchDestionationHistory, "_id = " + destination.getId(), null); - database.setTransactionSuccessful(); - return true; - } catch (Exception e) { - Log.e("Unable to remove searched destination", e); - } finally { - database.endTransaction(); - } - - return false; - } - - /** - * Load the lazily initialized fields of a cache and return them as partial cache (all other fields unset). - * - * @param geocode - * @return - */ - public static Geocache loadCacheTexts(final String geocode) { - final Geocache partial = new Geocache(); - - // in case of database issues, we still need to return a result to avoid endless loops - partial.setDescription(StringUtils.EMPTY); - partial.setShortDescription(StringUtils.EMPTY); - partial.setHint(StringUtils.EMPTY); - partial.setLocation(StringUtils.EMPTY); - - init(); - - try { - final Cursor cursor = database.query( - dbTableCaches, - new String[] { "description", "shortdesc", "hint", "location" }, - "geocode = ?", - new String[] { geocode }, - null, - null, - null, - "1"); - - if (cursor.moveToFirst()) { - partial.setDescription(StringUtils.defaultString(cursor.getString(0))); - partial.setShortDescription(StringUtils.defaultString(cursor.getString(1))); - partial.setHint(StringUtils.defaultString(cursor.getString(2))); - partial.setLocation(StringUtils.defaultString(cursor.getString(3))); - } - - cursor.close(); - } catch (SQLiteDoneException e) { - // Do nothing, it only means we have no information on the cache - } catch (Exception e) { - Log.e("cgData.getCacheDescription", e); - } - - return partial; - } - - /** - * checks if this is a newly created database - */ - public static boolean isNewlyCreatedDatebase() { - return newlyCreatedDatabase; - } - - /** - * resets flag for newly created database to avoid asking the user multiple times - */ - public static void resetNewlyCreatedDatabase() { - newlyCreatedDatabase = false; - } - - /** - * Creates the WHERE clause for matching multiple geocodes. This automatically converts all given codes to - * UPPERCASE. - */ - private static StringBuilder whereGeocodeIn(Set geocodes) { - final StringBuilder where = new StringBuilder(); - - if (geocodes != null && !geocodes.isEmpty()) { - StringBuilder all = new StringBuilder(); - for (String geocode : geocodes) { - if (all.length() > 0) { - all.append(','); - } - all.append(DatabaseUtils.sqlEscapeString(StringUtils.upperCase(geocode))); - } - - where.append("geocode in (").append(all).append(')'); - } - - return where; - } - - /** - * Loads all Waypoints in the coordinate rectangle. - * - * @param excludeDisabled - * @param excludeMine - * @param type - * @return - */ - - public static Set loadWaypoints(final Viewport viewport, boolean excludeMine, boolean excludeDisabled, CacheType type) { - final StringBuilder where = new StringBuilder(buildCoordinateWhere(dbTableWaypoints, viewport)); - if (excludeMine) { - where.append(" and ").append(dbTableCaches).append(".found == 0"); - } - if (excludeDisabled) { - where.append(" and ").append(dbTableCaches).append(".disabled == 0"); - } - if (type != CacheType.ALL) { - where.append(" and ").append(dbTableCaches).append(".type == '").append(type.id).append('\''); - } - init(); - - final StringBuilder query = new StringBuilder("SELECT "); - for (int i = 0; i < WAYPOINT_COLUMNS.length; i++) { - query.append(i > 0 ? ", " : "").append(dbTableWaypoints).append('.').append(WAYPOINT_COLUMNS[i]).append(' '); - } - query.append(" FROM ").append(dbTableWaypoints).append(", ").append(dbTableCaches).append(" WHERE ").append(dbTableWaypoints).append(".geocode == ").append(dbTableCaches).append(".geocode and ").append(where); - - final Set waypoints = new HashSet(); - final Cursor cursor = database.rawQuery(query.toString(), null); - while (cursor.moveToNext()) { - waypoints.add(createWaypointFromDatabaseContent(cursor)); - } - cursor.close(); - return waypoints; - } - - public static String[] getTrackableCodes() { - init(); - - final Cursor cursor = database.query( - dbTableTrackables, - new String[] { "tbcode" }, - null, - null, - null, - null, - "updated DESC", - "100"); - return getFirstColumn(cursor); - } - - /** - * Extract the first column of the cursor rows and close the cursor. - * - * @param cursor a database cursor - * @return the first column of each row - */ - private static String[] getFirstColumn(final Cursor cursor) { - final String[] result = new String[cursor.getCount()]; - for (int i = 0; cursor.moveToNext(); i++) { - result[i] = cursor.getString(0); - } - cursor.close(); - return result; - } - - public static boolean saveChangedCache(Geocache cache) { - return cgData.saveCache(cache, cache.getStorageLocation().contains(StorageLocation.DATABASE) ? LoadFlags.SAVE_ALL : EnumSet.of(SaveFlag.SAVE_CACHE)); - } - - private static class PreparedStatements { - - private static HashMap statements = new HashMap(); - - public static SQLiteStatement getMoveToStandardList() { - return getStatement("MoveToStandardList", "UPDATE " + dbTableCaches + " SET reason = " + StoredList.STANDARD_LIST_ID + " WHERE reason = ?"); - } - - public static SQLiteStatement getMoveToList() { - return getStatement("MoveToList", "UPDATE " + dbTableCaches + " SET reason = ? WHERE geocode = ?"); - } - - public static SQLiteStatement getUpdateVisitDate() { - return getStatement("UpdateVisitDate", "UPDATE " + dbTableCaches + " SET visiteddate = ? WHERE geocode = ?"); - } - - public static SQLiteStatement getInsertLogImage() { - return getStatement("InsertLogImage", "INSERT INTO " + dbTableLogImages + " (log_id, title, url) VALUES (?, ?, ?)"); - } - - public static SQLiteStatement getInsertLogCounts() { - return getStatement("InsertLogCounts", "INSERT INTO " + dbTableLogCount + " (geocode, updated, type, count) VALUES (?, ?, ?, ?)"); - } - - public static SQLiteStatement getInsertSpoiler() { - return getStatement("InsertSpoiler", "INSERT INTO " + dbTableSpoilers + " (geocode, updated, url, title, description) VALUES (?, ?, ?, ?, ?)"); - } - - public static SQLiteStatement getInsertSearchDestination(Destination destination) { - final SQLiteStatement statement = getStatement("InsertSearch", "INSERT INTO " + dbTableSearchDestionationHistory + " (date, latitude, longitude) VALUES (?, ?, ?)"); - statement.bindLong(1, destination.getDate()); - final Geopoint coords = destination.getCoords(); - statement.bindDouble(2, coords.getLatitude()); - statement.bindDouble(3, coords.getLongitude()); - return statement; - } - - private static void clearPreparedStatements() { - for (SQLiteStatement statement : statements.values()) { - statement.close(); - } - statements.clear(); - } - - private static synchronized SQLiteStatement getStatement(final String key, final String query) { - SQLiteStatement statement = statements.get(key); - if (statement == null) { - init(); - statement = database.compileStatement(query); - statements.put(key, statement); - } - return statement; - } - - public static SQLiteStatement getCountHistoryCaches() { - return getStatement("HistoryCount", "select count(_id) from " + dbTableCaches + " where visiteddate > 0"); - } - - private static SQLiteStatement getLogCountOfGeocode() { - return getStatement("LogCountFromGeocode", "SELECT count(_id) FROM " + cgData.dbTableLogsOffline + " WHERE geocode = ?"); - } - - private static SQLiteStatement getCountCachesOnStandardList() { - return getStatement("CountStandardList", "SELECT count(_id) FROM " + dbTableCaches + " WHERE reason = " + StoredList.STANDARD_LIST_ID); - } - - private static SQLiteStatement getCountAllCaches() { - return getStatement("CountAllLists", "SELECT count(_id) FROM " + dbTableCaches + " WHERE reason >= " + StoredList.STANDARD_LIST_ID); - } - - private static SQLiteStatement getInsertLog() { - return getStatement("InsertLog", "INSERT INTO " + dbTableLogs + " (geocode, updated, type, author, log, date, found, friend) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - } - - private static SQLiteStatement getInsertAttribute() { - return getStatement("InsertAttribute", "INSERT INTO " + dbTableAttributes + " (geocode, updated, attribute) VALUES (?, ?, ?)"); - } - - private static SQLiteStatement getListIdOfGeocode() { - return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE geocode = ?"); - } - - private static SQLiteStatement getListIdOfGuid() { - return getStatement("listFromGeocode", "SELECT reason FROM " + dbTableCaches + " WHERE guid = ?"); - } - - private static SQLiteStatement getCacheIdOfGeocode() { - return getStatement("cacheIdFromGeocode", "SELECT cacheid FROM " + dbTableCaches + " WHERE geocode = ?"); - } - - private static SQLiteStatement getGeocodeOfGuid() { - return getStatement("geocodeFromGuid", "SELECT geocode FROM " + dbTableCaches + " WHERE guid = ?"); - } - - } - - public static void saveVisitDate(final String geocode) { - setVisitDate(Collections.singletonList(geocode), System.currentTimeMillis()); - } - - public static void markDropped(List caches) { - moveToList(caches, StoredList.TEMPORARY_LIST_ID); - } - - public static Viewport getBounds(String geocode) { - if (geocode == null) { - return null; - } - - return cgData.getBounds(Collections.singleton(geocode)); - } - - public static void clearVisitDate(String[] selected) { - setVisitDate(Arrays.asList(selected), 0); - } - - public static SearchResult getBatchOfStoredCaches(Geopoint coords, CacheType cacheType, int listId) { - final Set geocodes = cgData.loadBatchOfStoredGeocodes(coords, cacheType, listId); - return new SearchResult(geocodes, cgData.getAllStoredCachesCount(cacheType, listId)); - } - - public static SearchResult getHistoryOfCaches(boolean detailedOnly, CacheType cacheType) { - final Set geocodes = cgData.loadBatchOfHistoricGeocodes(detailedOnly, cacheType); - return new SearchResult(geocodes, cgData.getAllHistoryCachesCount()); - } - - public static boolean saveWaypoint(int id, String geocode, Waypoint waypoint) { - if (cgData.saveWaypointInternal(id, geocode, waypoint)) { - cgData.removeCache(geocode, EnumSet.of(RemoveFlag.REMOVE_CACHE)); - return true; - } - return false; - } - - public static Set getCachedMissingFromSearch(final SearchResult searchResult, final Set tiles, final IConnector connector, final int maxZoom) { - - // get cached cgeocaches - final Set cachedGeocodes = new HashSet(); - for (Tile tile : tiles) { - cachedGeocodes.addAll(cacheCache.getInViewport(tile.getViewport(), CacheType.ALL)); - } - // remove found in search result - cachedGeocodes.removeAll(searchResult.getGeocodes()); - - // check remaining against viewports - Set missingFromSearch = new HashSet(); - for (String geocode : cachedGeocodes) { - if (connector.canHandle(geocode)) { - Geocache geocache = cacheCache.getCacheFromCache(geocode); - if (geocache.getCoordZoomLevel() <= maxZoom) { - boolean found = false; - for (Tile tile : tiles) { - if (tile.containsPoint(geocache)) { - found = true; - break; - } - } - if (found) { - missingFromSearch.add(geocode); - } - } - } - } - - return missingFromSearch; - } - -} diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java index 5a793f5..403f597 100644 --- a/main/src/cgeo/geocaching/cgeoapplication.java +++ b/main/src/cgeo/geocaching/cgeoapplication.java @@ -46,15 +46,15 @@ public class cgeoapplication extends Application { @Override public void onLowMemory() { Log.i("Cleaning applications cache."); - cgData.removeAllFromCache(); + DataStore.removeAllFromCache(); } @Override public void onTerminate() { Log.d("Terminating c:geo…"); - cgData.clean(); - cgData.closeDb(); + DataStore.clean(); + DataStore.closeDb(); super.onTerminate(); } @@ -82,7 +82,7 @@ public class cgeoapplication extends Application { @Override public void run() { - atomic.set(cgData.moveDatabase()); + atomic.set(DataStore.moveDatabase()); handler.sendMessage(handler.obtainMessage()); } }; diff --git a/main/src/cgeo/geocaching/cgeocaches.java b/main/src/cgeo/geocaching/cgeocaches.java index 423e9c6..2c791a4 100644 --- a/main/src/cgeo/geocaching/cgeocaches.java +++ b/main/src/cgeo/geocaching/cgeocaches.java @@ -469,7 +469,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity private boolean isConcreteList() { return type == CacheListType.OFFLINE && - (listId == StoredList.STANDARD_LIST_ID || listId >= cgData.customListIdOffset); + (listId == StoredList.STANDARD_LIST_ID || listId >= DataStore.customListIdOffset); } private boolean isInvokedFromAttachment() { @@ -503,7 +503,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity // refresh standard list if it has changed (new caches downloaded) if (type == CacheListType.OFFLINE && listId >= StoredList.STANDARD_LIST_ID && search != null) { - final SearchResult newSearch = cgData.getBatchOfStoredCaches(coords, Settings.getCacheType(), listId); + final SearchResult newSearch = DataStore.getBatchOfStoredCaches(coords, Settings.getCacheType(), listId); if (newSearch.getTotal() != search.getTotal()) { refreshCurrentList(); } @@ -643,7 +643,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity item.setVisible(isNonDefaultList); } - final boolean multipleLists = cgData.getLists().size() >= 2; + final boolean multipleLists = DataStore.getLists().size() >= 2; item = menu.findItem(MENU_SWITCH_LIST); if (item != null) { item.setVisible(multipleLists); @@ -866,7 +866,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity @Override public void run(Integer newListId) { - cgData.moveToList(adapter.getCheckedOrAllCaches(), newListId); + DataStore.moveToList(adapter.getCheckedOrAllCaches(), newListId); adapter.setSelectMode(false); refreshCurrentList(); @@ -924,7 +924,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity @Override public void run(Integer newListId) { - cgData.moveToList(Collections.singletonList(cache), newListId); + DataStore.moveToList(Collections.singletonList(cache), newListId); adapter.setSelectMode(false); refreshCurrentList(); } @@ -1385,7 +1385,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity @Override protected Void doInBackgroundInternal(Geocache[] caches) { removeGeoAndDir(); - cgData.markDropped(Arrays.asList(caches)); + DataStore.markDropped(Arrays.asList(caches)); startGeoAndDir(); return null; } @@ -1416,7 +1416,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity @Override public void run() { - cgData.clearLogsOffline(selected); + DataStore.clearLogsOffline(selected); handler.sendEmptyMessage(MSG_DONE); } } @@ -1468,7 +1468,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity return; } - final StoredList list = cgData.getList(id); + final StoredList list = DataStore.getList(id); if (list == null) { return; } @@ -1480,7 +1480,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity showProgress(true); showFooterLoadingCaches(); - cgData.moveToList(adapter.getCheckedCaches(), listId); + DataStore.moveToList(adapter.getCheckedCaches(), listId); currentLoader = (OfflineGeocacheListLoader) getSupportLoaderManager().initLoader(CacheListType.OFFLINE.ordinal(), new Bundle(), this); currentLoader.reset(); @@ -1503,7 +1503,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity } private void removeListInternal() { - if (cgData.removeList(listId)) { + if (DataStore.removeList(listId)) { showToast(res.getString(R.string.list_dialog_remove_ok)); switchListById(StoredList.STANDARD_LIST_ID); } else { @@ -1701,7 +1701,7 @@ public class cgeocaches extends AbstractListActivity implements FilteredActivity listId = StoredList.STANDARD_LIST_ID; title = res.getString(R.string.stored_caches_button); } else { - final StoredList list = cgData.getList(listId); + final StoredList list = DataStore.getList(listId); // list.id may be different if listId was not valid listId = list.id; title = list.title; diff --git a/main/src/cgeo/geocaching/connector/gc/GCConnector.java b/main/src/cgeo/geocaching/connector/gc/GCConnector.java index 9ac9c9d..066e656 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCConnector.java +++ b/main/src/cgeo/geocaching/connector/gc/GCConnector.java @@ -1,11 +1,11 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.ICache; import cgeo.geocaching.LogCacheActivity; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.AbstractConnector; import cgeo.geocaching.connector.ILoggingManager; @@ -137,10 +137,10 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, if (StringUtils.isEmpty(page)) { final SearchResult search = new SearchResult(); - if (cgData.isThere(geocode, guid, true, false)) { + if (DataStore.isThere(geocode, guid, true, false)) { if (StringUtils.isBlank(geocode) && StringUtils.isNotBlank(guid)) { Log.i("Loading old cache from cache."); - search.addGeocode(cgData.getGeocodeForGuid(guid)); + search.addGeocode(DataStore.getGeocodeForGuid(guid)); } else { search.addGeocode(geocode); } @@ -189,7 +189,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean addToWatchlist(Geocache cache) { final boolean added = GCParser.addToWatchlist(cache); if (added) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return added; } @@ -198,7 +198,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean removeFromWatchlist(Geocache cache) { final boolean removed = GCParser.removeFromWatchlist(cache); if (removed) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return removed; } @@ -215,7 +215,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public static boolean addToFavorites(Geocache cache) { final boolean added = GCParser.addToFavorites(cache); if (added) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return added; } @@ -232,7 +232,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public static boolean removeFromFavorites(Geocache cache) { final boolean removed = GCParser.removeFromFavorites(cache); if (removed) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return removed; } @@ -241,7 +241,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean uploadModifiedCoordinates(Geocache cache, Geopoint wpt) { final boolean uploaded = GCParser.uploadModifiedCoordinates(cache, wpt); if (uploaded) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return uploaded; } @@ -250,7 +250,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean deleteModifiedCoordinates(Geocache cache) { final boolean deleted = GCParser.deleteModifiedCoordinates(cache); if (deleted) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return deleted; } @@ -259,7 +259,7 @@ public class GCConnector extends AbstractConnector implements ISearchByGeocode, public boolean uploadPersonalNote(Geocache cache) { final boolean uploaded = GCParser.uploadPersonalNote(cache); if (uploaded) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return uploaded; } diff --git a/main/src/cgeo/geocaching/connector/gc/GCMap.java b/main/src/cgeo/geocaching/connector/gc/GCMap.java index 27d8a77..e3259c0 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCMap.java +++ b/main/src/cgeo/geocaching/connector/gc/GCMap.java @@ -1,8 +1,8 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; @@ -361,7 +361,7 @@ public class GCMap { // Check for vanished found caches if (tiles.iterator().next().getZoomLevel() >= Tile.ZOOMLEVEL_MIN_PERSONALIZED) { - searchResult.addFilteredGeocodes(cgData.getCachedMissingFromSearch(searchResult, tiles, GCConnector.getInstance(), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1)); + searchResult.addFilteredGeocodes(DataStore.getCachedMissingFromSearch(searchResult, tiles, GCConnector.getInstance(), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1)); } } @@ -372,7 +372,7 @@ public class GCMap { SearchResult search = GCParser.searchByCoords(center, Settings.getCacheType(), false, null); if (search != null && !search.isEmpty()) { final Set geocodes = search.getGeocodes(); - lastSearchViewport = cgData.getBounds(geocodes); + lastSearchViewport = DataStore.getBounds(geocodes); searchResult.addGeocodes(geocodes); } } diff --git a/main/src/cgeo/geocaching/connector/gc/GCParser.java b/main/src/cgeo/geocaching/connector/gc/GCParser.java index 7eacb8e..f25fa1f 100644 --- a/main/src/cgeo/geocaching/connector/gc/GCParser.java +++ b/main/src/cgeo/geocaching/connector/gc/GCParser.java @@ -1,5 +1,6 @@ package cgeo.geocaching.connector.gc; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; @@ -8,7 +9,6 @@ import cgeo.geocaching.SearchResult; import cgeo.geocaching.Trackable; import cgeo.geocaching.TrackableLog; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; @@ -357,7 +357,7 @@ public abstract class GCParser { // save full detailed caches CancellableHandler.sendLoadProgressDetail(handler, R.string.cache_dialog_loading_details_status_cache); - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); // update progress message so user knows we're still working. This is more of a place holder than // actual indication of what the program is doing @@ -1094,7 +1094,7 @@ public abstract class GCParser { Log.i("Log successfully posted to cache #" + cacheid); if (geocode != null) { - cgData.saveVisitDate(geocode); + DataStore.saveVisitDate(geocode); } Login.getLoginStatus(page); @@ -1539,7 +1539,7 @@ public abstract class GCParser { } if (cgeoapplication.getInstance() != null) { - cgData.saveTrackable(trackable); + DataStore.saveTrackable(trackable); } return trackable; diff --git a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java index 663bbf7..89327f1 100644 --- a/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java +++ b/main/src/cgeo/geocaching/connector/oc/OCApiLiveConnector.java @@ -1,9 +1,9 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogCacheActivity; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ILoggingManager; import cgeo.geocaching.connector.capability.ILogin; @@ -87,7 +87,7 @@ public class OCApiLiveConnector extends OCApiConnector implements ISearchByCente final boolean added = OkapiClient.setWatchState(cache, true, this); if (added) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return added; @@ -98,7 +98,7 @@ public class OCApiLiveConnector extends OCApiConnector implements ISearchByCente final boolean removed = OkapiClient.setWatchState(cache, false, this); if (removed) { - cgData.saveChangedCache(cache); + DataStore.saveChangedCache(cache); } return removed; diff --git a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java index 189b6a4..61fde59 100644 --- a/main/src/cgeo/geocaching/connector/oc/OkapiClient.java +++ b/main/src/cgeo/geocaching/connector/oc/OkapiClient.java @@ -1,11 +1,11 @@ package cgeo.geocaching.connector.oc; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.Image; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.connector.IConnector; @@ -265,7 +265,7 @@ final class OkapiClient { parseCoreCache(response, cache); - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_CACHE)); } catch (final JSONException e) { Log.e("OkapiClient.parseSmallCache", e); } @@ -340,7 +340,7 @@ final class OkapiClient { cache.setDetailedUpdatedNow(); // save full detailed caches - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); } catch (final JSONException e) { Log.e("OkapiClient.parseCache", e); } diff --git a/main/src/cgeo/geocaching/export/FieldnoteExport.java b/main/src/cgeo/geocaching/export/FieldnoteExport.java index d0040a9..16c8780 100644 --- a/main/src/cgeo/geocaching/export/FieldnoteExport.java +++ b/main/src/cgeo/geocaching/export/FieldnoteExport.java @@ -3,7 +3,7 @@ package cgeo.geocaching.export; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.connector.gc.Login; import cgeo.geocaching.enumerations.StatusCode; @@ -134,7 +134,7 @@ class FieldnoteExport extends AbstractExport { int i = 0; for (final Geocache cache : caches) { if (cache.isLogOffline()) { - final LogEntry log = cgData.loadLogOffline(cache.getGeocode()); + final LogEntry log = DataStore.loadLogOffline(cache.getGeocode()); if (!onlyNew || log.date > Settings.getFieldnoteExportDate()) { appendFieldNote(fieldNoteBuffer, cache, log); } diff --git a/main/src/cgeo/geocaching/export/GpxSerializer.java b/main/src/cgeo/geocaching/export/GpxSerializer.java index 1e39be4..e4051b5 100644 --- a/main/src/cgeo/geocaching/export/GpxSerializer.java +++ b/main/src/cgeo/geocaching/export/GpxSerializer.java @@ -1,9 +1,9 @@ package cgeo.geocaching.export; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheAttribute; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.Geopoint; @@ -81,7 +81,7 @@ public final class GpxSerializer { } private void exportBatch(final XmlSerializer gpx, Collection geocodesOfBatch) throws IOException { - final Set caches = cgData.loadCaches(geocodesOfBatch, LoadFlags.LOAD_ALL_DB_ONLY); + final Set caches = DataStore.loadCaches(geocodesOfBatch, LoadFlags.LOAD_ALL_DB_ONLY); for (final Geocache cache : caches) { gpx.startTag(PREFIX_GPX, "wpt"); gpx.attribute("", "lat", Double.toString(cache.getCoords().getLatitude())); diff --git a/main/src/cgeo/geocaching/files/GPXImporter.java b/main/src/cgeo/geocaching/files/GPXImporter.java index 3f11c26..bf0aa72 100644 --- a/main/src/cgeo/geocaching/files/GPXImporter.java +++ b/main/src/cgeo/geocaching/files/GPXImporter.java @@ -4,7 +4,7 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.StaticMapsProvider; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.activity.Progress; import cgeo.geocaching.enumerations.LoadFlags; @@ -175,7 +175,7 @@ public class GPXImporter { private boolean importStaticMaps(final SearchResult importedCaches) { int storedCacheMaps = 0; for (final String geocode : importedCaches.getGeocodes()) { - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); if (cache != null) { Log.d("GPXImporter.ImportThread.importStaticMaps start downloadMaps for cache " + geocode); StaticMapsProvider.downloadMaps(cache); diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java index 3358759..431a529 100644 --- a/main/src/cgeo/geocaching/files/GPXParser.java +++ b/main/src/cgeo/geocaching/files/GPXParser.java @@ -1,12 +1,12 @@ package cgeo.geocaching.files; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; import cgeo.geocaching.StoredList; import cgeo.geocaching.Trackable; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.connector.ConnectorFactory; import cgeo.geocaching.enumerations.CacheSize; @@ -312,10 +312,10 @@ public abstract class GPXParser extends FileParser { // finally store the cache in the database result.add(geocode); - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); // avoid the cachecache using lots of memory for caches which the user did not actually look at - cgData.removeAllFromCache(); + DataStore.removeAllFromCache(); showProgressMessage(progressHandler, progressStream.getProgress()); } else if (StringUtils.isNotBlank(cache.getName()) && StringUtils.containsIgnoreCase(type, "waypoint")) { @@ -331,7 +331,7 @@ public abstract class GPXParser extends FileParser { if (cache.getName().length() > 2) { final String cacheGeocodeForWaypoint = "GC" + cache.getName().substring(2).toUpperCase(Locale.US); // lookup cache for waypoint in already parsed caches - final Geocache cacheForWaypoint = cgData.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cacheForWaypoint = DataStore.loadCache(cacheGeocodeForWaypoint, LoadFlags.LOAD_CACHE_OR_DB); if (cacheForWaypoint != null) { final Waypoint waypoint = new Waypoint(cache.getShortDescription(), convertWaypointSym2Type(sym), false); waypoint.setId(-1); @@ -349,7 +349,7 @@ public abstract class GPXParser extends FileParser { newPoints.add(waypoint); Waypoint.mergeWayPoints(newPoints, mergedWayPoints, true); cacheForWaypoint.setWaypoints(newPoints, false); - cgData.saveCache(cacheForWaypoint, EnumSet.of(SaveFlag.SAVE_DB)); + DataStore.saveCache(cacheForWaypoint, EnumSet.of(SaveFlag.SAVE_DB)); showProgressMessage(progressHandler, progressStream.getProgress()); } } @@ -785,7 +785,7 @@ public abstract class GPXParser extends FileParser { try { progressStream = new ProgressInputStream(stream); Xml.parse(progressStream, Xml.Encoding.UTF_8, root.getContentHandler()); - return cgData.loadCaches(result, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); + return DataStore.loadCaches(result, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); } catch (final SAXException e) { Log.w("Cannot parse .gpx file as GPX " + version + ": could not parse XML - ", e); throw new ParserException("Cannot parse .gpx file as GPX " + version + ": could not parse XML", e); diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java index 1cfb2a3..3d01c1b 100644 --- a/main/src/cgeo/geocaching/files/LocParser.java +++ b/main/src/cgeo/geocaching/files/LocParser.java @@ -1,8 +1,8 @@ package cgeo.geocaching.files; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; @@ -59,7 +59,7 @@ public final class LocParser extends FileParser { contained.add(geocode); } } - Set caches = cgData.loadCaches(contained, LoadFlags.LOAD_CACHE_OR_DB); + Set caches = DataStore.loadCaches(contained, LoadFlags.LOAD_CACHE_OR_DB); for (Geocache cache : caches) { Geocache coord = cidCoords.get(cache.getGeocode()); copyCoordToCache(coord, cache); diff --git a/main/src/cgeo/geocaching/filter/AttributeFilter.java b/main/src/cgeo/geocaching/filter/AttributeFilter.java index cadcf49..0b4279f 100644 --- a/main/src/cgeo/geocaching/filter/AttributeFilter.java +++ b/main/src/cgeo/geocaching/filter/AttributeFilter.java @@ -1,8 +1,8 @@ package cgeo.geocaching.filter; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.R; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.LoadFlags.LoadFlag; @@ -29,7 +29,7 @@ class AttributeFilter extends AbstractFilter { @Override public boolean accepts(final Geocache cache) { - Geocache fullCache = cgData.loadCache(cache.getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); + Geocache fullCache = DataStore.loadCache(cache.getGeocode(), EnumSet.of(LoadFlag.LOAD_ATTRIBUTES)); if (fullCache == null) { fullCache = cache; } diff --git a/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java index 722f9f5..605f461 100644 --- a/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java +++ b/main/src/cgeo/geocaching/loaders/HistoryGeocacheListLoader.java @@ -1,8 +1,8 @@ package cgeo.geocaching.loaders; +import cgeo.geocaching.DataStore; import cgeo.geocaching.SearchResult; import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Geopoint; @@ -18,7 +18,7 @@ public class HistoryGeocacheListLoader extends AbstractSearchLoader { @Override public SearchResult runSearch() { - return cgData.getHistoryOfCaches(true, coords != null ? Settings.getCacheType() : CacheType.ALL); + return DataStore.getHistoryOfCaches(true, coords != null ? Settings.getCacheType() : CacheType.ALL); } } diff --git a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java index ab8ba6a..5088484 100644 --- a/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java +++ b/main/src/cgeo/geocaching/loaders/OfflineGeocacheListLoader.java @@ -2,7 +2,7 @@ package cgeo.geocaching.loaders; import cgeo.geocaching.SearchResult; import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.geopoint.Geopoint; import android.content.Context; @@ -20,7 +20,7 @@ public class OfflineGeocacheListLoader extends AbstractSearchLoader { @Override public SearchResult runSearch() { - return cgData.getBatchOfStoredCaches(searchCenter, Settings.getCacheType(), listId); + return DataStore.getBatchOfStoredCaches(searchCenter, Settings.getCacheType(), listId); } public void setListId(int listId) { diff --git a/main/src/cgeo/geocaching/loaders/RemoveFromHistoryLoader.java b/main/src/cgeo/geocaching/loaders/RemoveFromHistoryLoader.java index 2229afe..8ca0fa5 100644 --- a/main/src/cgeo/geocaching/loaders/RemoveFromHistoryLoader.java +++ b/main/src/cgeo/geocaching/loaders/RemoveFromHistoryLoader.java @@ -1,8 +1,8 @@ package cgeo.geocaching.loaders; +import cgeo.geocaching.DataStore; import cgeo.geocaching.SearchResult; import cgeo.geocaching.settings.Settings; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.geopoint.Geopoint; @@ -21,8 +21,8 @@ public class RemoveFromHistoryLoader extends AbstractSearchLoader { @Override public SearchResult runSearch() { - cgData.clearVisitDate(selected); - return cgData.getHistoryOfCaches(true, coords != null ? Settings.getCacheType() : CacheType.ALL); + DataStore.clearVisitDate(selected); + return DataStore.getHistoryOfCaches(true, coords != null ? Settings.getCacheType() : CacheType.ALL); } } diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java index 0703dd8..2677b33 100644 --- a/main/src/cgeo/geocaching/maps/CGeoMap.java +++ b/main/src/cgeo/geocaching/maps/CGeoMap.java @@ -7,7 +7,7 @@ import cgeo.geocaching.R; import cgeo.geocaching.SearchResult; import cgeo.geocaching.StoredList; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.cgeocaches; import cgeo.geocaching.activity.ActivityMixin; @@ -361,7 +361,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto activity = this.getActivity(); app = (cgeoapplication) activity.getApplication(); - int countBubbleCnt = cgData.getAllCachesCount(); + int countBubbleCnt = DataStore.getAllCachesCount(); caches = new LeastRecentlyUsedSet(MAX_CACHES + countBubbleCnt); final MapProvider mapProvider = Settings.getMapProvider(); @@ -491,7 +491,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto if (!CollectionUtils.isEmpty(dirtyCaches)) { for (String geocode : dirtyCaches) { - Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); + Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_WAYPOINTS); if (cache != null) { // new collection type needs to remove first caches.remove(cache); @@ -641,7 +641,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto final List geocodes = new ArrayList(); for (final String geocode : geocodesInViewport) { - if (!cgData.isOffline(geocode, null)) { + if (!DataStore.isOffline(geocode, null)) { geocodes.add(geocode); } } @@ -1090,7 +1090,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto SearchResult searchResult; if (mapMode == MapMode.LIVE) { - searchResult = isLiveEnabled ? new SearchResult() : new SearchResult(cgData.loadStoredInViewport(viewport, Settings.getCacheType())); + searchResult = isLiveEnabled ? new SearchResult() : new SearchResult(DataStore.loadStoredInViewport(viewport, Settings.getCacheType())); } else { // map started from another activity searchResult = searchIntent != null ? new SearchResult(searchIntent) : new SearchResult(); @@ -1100,7 +1100,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto } // live mode search result if (isLiveEnabled) { - searchResult.addSearchResult(cgData.loadCachedInViewport(viewport, Settings.getCacheType())); + searchResult.addSearchResult(DataStore.loadCachedInViewport(viewport, Settings.getCacheType())); } downloaded = true; @@ -1123,7 +1123,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto || mapMode == MapMode.COORDS) { //All visible waypoints CacheType type = Settings.getCacheType(); - Set waypointsInViewport = cgData.loadWaypoints(viewport, excludeMine, excludeDisabled, type); + Set waypointsInViewport = DataStore.loadWaypoints(viewport, excludeMine, excludeDisabled, type); waypoints.addAll(waypointsInViewport); } else { @@ -1196,8 +1196,8 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto // first remove filtered out final Set filteredCodes = searchResult.getFilteredGeocodes(); Log.d("Filtering out " + filteredCodes.size() + " caches: " + filteredCodes.toString()); - caches.removeAll(cgData.loadCaches(filteredCodes, LoadFlags.LOAD_CACHE_ONLY)); - cgData.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.REMOVE_CACHE)); + caches.removeAll(DataStore.loadCaches(filteredCodes, LoadFlags.LOAD_CACHE_ONLY)); + DataStore.removeCaches(filteredCodes, EnumSet.of(RemoveFlag.REMOVE_CACHE)); // new collection type needs to remove first to refresh caches.removeAll(result); caches.addAll(result); @@ -1409,7 +1409,7 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto break; } - if (!cgData.isOffline(geocode, null)) { + if (!DataStore.isOffline(geocode, null)) { if ((System.currentTimeMillis() - last) < 1500) { try { int delay = 1000 + (int) (Math.random() * 1000.0) - (int) (System.currentTimeMillis() - last); @@ -1512,9 +1512,9 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto Viewport viewport = null; if (geocodeCenter != null) { - viewport = cgData.getBounds(geocodeCenter); + viewport = DataStore.getBounds(geocodeCenter); } else if (searchCenter != null) { - viewport = cgData.getBounds(searchCenter.getGeocodes()); + viewport = DataStore.getBounds(searchCenter.getGeocodes()); } if (viewport == null) { diff --git a/main/src/cgeo/geocaching/maps/CachesOverlay.java b/main/src/cgeo/geocaching/maps/CachesOverlay.java index 8fbb3db..cd2ff75 100644 --- a/main/src/cgeo/geocaching/maps/CachesOverlay.java +++ b/main/src/cgeo/geocaching/maps/CachesOverlay.java @@ -5,7 +5,7 @@ import cgeo.geocaching.Geocache; import cgeo.geocaching.IWaypoint; import cgeo.geocaching.R; import cgeo.geocaching.WaypointPopup; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.activity.Progress; import cgeo.geocaching.connector.gc.GCMap; import cgeo.geocaching.enumerations.CacheType; @@ -228,7 +228,7 @@ public class CachesOverlay extends AbstractItemizedOverlay { final IWaypoint coordinate = item.getCoord(); if (StringUtils.isNotBlank(coordinate.getCoordType()) && coordinate.getCoordType().equalsIgnoreCase("cache") && StringUtils.isNotBlank(coordinate.getGeocode())) { - Geocache cache = cgData.loadCache(coordinate.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); + Geocache cache = DataStore.loadCache(coordinate.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); RequestDetailsThread requestDetailsThread = new RequestDetailsThread(cache); if (!requestDetailsThread.requestRequired()) { // don't show popup if we have enough details diff --git a/main/src/cgeo/geocaching/sorting/FindsComparator.java b/main/src/cgeo/geocaching/sorting/FindsComparator.java index ba929b8..b147fad 100644 --- a/main/src/cgeo/geocaching/sorting/FindsComparator.java +++ b/main/src/cgeo/geocaching/sorting/FindsComparator.java @@ -1,7 +1,7 @@ package cgeo.geocaching.sorting; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.LogType; public class FindsComparator extends AbstractCacheComparator { @@ -20,7 +20,7 @@ public class FindsComparator extends AbstractCacheComparator { private static int getFindsCount(Geocache cache) { if (cache.getLogCounts().isEmpty()) { - cache.setLogCounts(cgData.loadLogCounts(cache.getGeocode())); + cache.setLogCounts(DataStore.loadLogCounts(cache.getGeocode())); } Integer logged = cache.getLogCounts().get(LogType.FOUND_IT); if (logged != null) { diff --git a/main/src/cgeo/geocaching/twitter/Twitter.java b/main/src/cgeo/geocaching/twitter/Twitter.java index 7233764..b339e28 100644 --- a/main/src/cgeo/geocaching/twitter/Twitter.java +++ b/main/src/cgeo/geocaching/twitter/Twitter.java @@ -1,8 +1,8 @@ package cgeo.geocaching.twitter; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.Trackable; -import cgeo.geocaching.cgData; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.geopoint.Geopoint; @@ -22,12 +22,12 @@ public final class Twitter { private static final int MAX_TWEET_SIZE = 140; public static void postTweetCache(String geocode) { - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); postTweet(cgeoapplication.getInstance(), getStatusMessage(cache), null); } public static void postTweetTrackable(String geocode) { - final Trackable trackable = cgData.loadTrackable(geocode); + final Trackable trackable = DataStore.loadTrackable(geocode); postTweet(cgeoapplication.getInstance(), getStatusMessage(trackable), null); } diff --git a/main/src/cgeo/geocaching/ui/LoggingUI.java b/main/src/cgeo/geocaching/ui/LoggingUI.java index c2e2d24..1423da2 100644 --- a/main/src/cgeo/geocaching/ui/LoggingUI.java +++ b/main/src/cgeo/geocaching/ui/LoggingUI.java @@ -1,9 +1,9 @@ package cgeo.geocaching.ui; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.R; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.settings.Settings; @@ -74,7 +74,7 @@ public class LoggingUI extends AbstractUIFactory { } private static void showOfflineMenu(final Geocache cache, final Activity activity) { - final LogEntry currentLog = cgData.loadLogOffline(cache.getGeocode()); + final LogEntry currentLog = DataStore.loadLogOffline(cache.getGeocode()); final LogType currentLogType = currentLog == null ? null : currentLog.type; final List logTypes = cache.getPossibleLogTypes(); diff --git a/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java b/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java index 8aa605f..5c8d641 100644 --- a/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java +++ b/main/src/cgeo/geocaching/utils/DatabaseBackupUtils.java @@ -1,8 +1,8 @@ package cgeo.geocaching.utils; +import cgeo.geocaching.DataStore; import cgeo.geocaching.MainActivity; import cgeo.geocaching.R; -import cgeo.geocaching.cgData; import cgeo.geocaching.activity.ActivityMixin; import cgeo.geocaching.ui.Formatter; @@ -50,7 +50,7 @@ public class DatabaseBackupUtils { @Override public void run() { - restoreSuccessful.set(cgData.restoreDatabaseInternal()); + restoreSuccessful.set(DataStore.restoreDatabaseInternal()); handler.sendMessage(handler.obtainMessage()); } }; @@ -61,7 +61,7 @@ public class DatabaseBackupUtils { final Context context = activity; // avoid overwriting an existing backup with an empty database // (can happen directly after reinstalling the app) - if (cgData.getAllCachesCount() == 0) { + if (DataStore.getAllCachesCount() == 0) { ActivityMixin.helpDialog(activity, context.getString(R.string.init_backup), context.getString(R.string.init_backup_unnecessary)); @@ -74,7 +74,7 @@ public class DatabaseBackupUtils { new Thread() { @Override public void run() { - final String backupFileName = cgData.backupDatabaseInternal(); + final String backupFileName = DataStore.backupDatabaseInternal(); activity.runOnUiThread(new Runnable() { @Override public void run() { @@ -96,7 +96,7 @@ public class DatabaseBackupUtils { } public static File getRestoreFile() { - final File fileSourceFile = cgData.getBackupFileInternal(); + final File fileSourceFile = DataStore.getBackupFileInternal(); return fileSourceFile.exists() && fileSourceFile.length() > 0 ? fileSourceFile : null; } diff --git a/tests/src/cgeo/CGeoTestCase.java b/tests/src/cgeo/CGeoTestCase.java index b741e95..fa2c7b5 100644 --- a/tests/src/cgeo/CGeoTestCase.java +++ b/tests/src/cgeo/CGeoTestCase.java @@ -1,6 +1,6 @@ package cgeo; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.cgeoapplication; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; @@ -29,7 +29,7 @@ public abstract class CGeoTestCase extends ApplicationTestCase /** Remove cache from DB and cache to ensure that the cache is not loaded from the database */ protected static void deleteCacheFromDB(String geocode) { - cgData.removeCache(geocode, LoadFlags.REMOVE_ALL); + DataStore.removeCache(geocode, LoadFlags.REMOVE_ALL); } /** @@ -40,7 +40,7 @@ public abstract class CGeoTestCase extends ApplicationTestCase protected static void removeCacheCompletely(final String geocode) { final EnumSet flags = EnumSet.copyOf(LoadFlags.REMOVE_ALL); flags.add(RemoveFlag.REMOVE_OWN_WAYPOINTS_ONLY_FOR_TESTING); - cgData.removeCache(geocode, flags); + DataStore.removeCache(geocode, flags); } /** diff --git a/tests/src/cgeo/geocaching/DataStoreTest.java b/tests/src/cgeo/geocaching/DataStoreTest.java new file mode 100644 index 0000000..3f0214b --- /dev/null +++ b/tests/src/cgeo/geocaching/DataStoreTest.java @@ -0,0 +1,228 @@ +package cgeo.geocaching; + +import cgeo.CGeoTestCase; +import cgeo.geocaching.connector.gc.GCConnector; +import cgeo.geocaching.connector.gc.Tile; +import cgeo.geocaching.enumerations.CacheType; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; +import cgeo.geocaching.geopoint.Geopoint; +import cgeo.geocaching.geopoint.Viewport; + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class DataStoreTest extends CGeoTestCase { + + public static void testStoredLists() { + + int listId1 = StoredList.STANDARD_LIST_ID; + int listId2 = StoredList.STANDARD_LIST_ID; + + // create caches + final Geocache cache1 = new Geocache(); + cache1.setGeocode("Cache 1"); + final Geocache cache2 = new Geocache(); + cache2.setGeocode("Cache 2"); + assertNotNull(cache2); + + try { + + // create lists + listId1 = DataStore.createList("DataStore Test"); + assertTrue(listId1 > StoredList.STANDARD_LIST_ID); + listId2 = DataStore.createList("DataStoreTest"); + assertTrue(listId2 > StoredList.STANDARD_LIST_ID); + assertTrue(DataStore.getLists().size() >= 2); + + cache1.setDetailed(true); + cache1.setListId(listId1); + cache2.setDetailed(true); + cache2.setListId(listId1); + + // save caches to DB (cache1=listId1, cache2=listId1) + DataStore.saveCache(cache1, LoadFlags.SAVE_ALL); + DataStore.saveCache(cache2, LoadFlags.SAVE_ALL); + assertTrue(DataStore.getAllCachesCount() >= 2); + + // rename list (cache1=listId1, cache2=listId1) + assertEquals(1, DataStore.renameList(listId1, "DataStore Test (renamed)")); + + // get list + final StoredList list1 = DataStore.getList(listId1); + assertEquals("DataStore Test (renamed)", list1.title); + + // move to list (cache1=listId2, cache2=listId2) + DataStore.moveToList(Collections.singletonList(cache1), listId2); + assertEquals(1, DataStore.getAllStoredCachesCount(CacheType.ALL, listId2)); + + // remove list (cache1=listId2, cache2=listId2) + assertTrue(DataStore.removeList(listId1)); + + // mark dropped (cache1=1, cache2=0) + DataStore.markDropped(Collections.singletonList(cache2)); + + // mark stored (cache1=1, cache2=listId2) + DataStore.moveToList(Collections.singletonList(cache2), listId2); + assertEquals(2, DataStore.getAllStoredCachesCount(CacheType.ALL, listId2)); + + // drop stored (cache1=0, cache2=0) + DataStore.removeList(listId2); + + } finally { + + // remove caches + final Set geocodes = new HashSet(); + geocodes.add(cache1.getGeocode()); + geocodes.add(cache2.getGeocode()); + DataStore.removeCaches(geocodes, LoadFlags.REMOVE_ALL); + + // remove list + DataStore.removeList(listId1); + DataStore.removeList(listId2); + } + } + + // Check that queries don't throw an exception (see issue #1429). + public static void testLoadWaypoints() { + final Viewport viewport = new Viewport(new Geopoint(-1, -2), new Geopoint(3, 4)); + DataStore.loadWaypoints(viewport, false, false, CacheType.ALL); + DataStore.loadWaypoints(viewport, false, true, CacheType.ALL); + DataStore.loadWaypoints(viewport, true, false, CacheType.ALL); + DataStore.loadWaypoints(viewport, true, true, CacheType.ALL); + DataStore.loadWaypoints(viewport, false, false, CacheType.TRADITIONAL); + DataStore.loadWaypoints(viewport, false, true, CacheType.TRADITIONAL); + DataStore.loadWaypoints(viewport, true, false, CacheType.TRADITIONAL); + DataStore.loadWaypoints(viewport, true, true, CacheType.TRADITIONAL); + } + + // Check that saving a cache and trackable without logs works (see #2199) + public static void testSaveWithoutLogs() { + + final String GEOCODE_CACHE = "TEST"; + + // create cache and trackable + final Geocache cache = new Geocache(); + cache.setGeocode(GEOCODE_CACHE); + cache.setDetailed(true); + final Trackable trackable = new Trackable(); + trackable.setLogs(null); + final List inventory = new ArrayList(); + inventory.add(trackable); + cache.setInventory(inventory); + + try { + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + final Geocache loadedCache = DataStore.loadCache(GEOCODE_CACHE, LoadFlags.LOAD_ALL_DB_ONLY); + assertNotNull("Cache was not saved!", loadedCache); + assertEquals(1, loadedCache.getInventory().size()); + } finally { + DataStore.removeCache(GEOCODE_CACHE, LoadFlags.REMOVE_ALL); + } + } + + // Check that loading a cache by case insensitive geo code works correctly (see #3139) + public static void testGeocodeCaseInsensitive() { + + final String GEOCODE_CACHE = "TEST"; + final String upperCase = GEOCODE_CACHE; + final String lowerCase = StringUtils.lowerCase(upperCase); + assertFalse(upperCase.equals(lowerCase)); + + // create cache and trackable + final Geocache cache = new Geocache(); + cache.setGeocode(upperCase); + cache.setDetailed(true); + + try { + final Geocache oldCache = DataStore.loadCache(upperCase, LoadFlags.LOAD_ALL_DB_ONLY); + assertNull("Database contained old cache!", oldCache); + + DataStore.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); + final Geocache cacheWithOriginalCode = DataStore.loadCache(upperCase, LoadFlags.LOAD_ALL_DB_ONLY); + assertNotNull("Cache was not saved correctly!", cacheWithOriginalCode); + + final Geocache cacheLowerCase = DataStore.loadCache(lowerCase, LoadFlags.LOAD_ALL_DB_ONLY); + assertNotNull("Could not find cache by case insensitive geocode", cacheLowerCase); + + } finally { + DataStore.removeCache(upperCase, LoadFlags.REMOVE_ALL); + } + } + + // Loading logs for an empty geocode should return an empty list, not null! + public static void testLoadLogsFromEmptyGeocode() { + + final List logs = DataStore.loadLogs(""); + + assertNotNull("Logs must not be null", logs); + assertEquals("Logs from empty geocode must be empty", 0, logs.size()); + } + + public static void testLoadCacheHistory() { + int sumCaches = 0; + int allCaches = 0; + for (CacheType cacheType : CacheType.values()) { + SearchResult historyOfType = DataStore.getHistoryOfCaches(false, cacheType); + assertNotNull(historyOfType); + if (cacheType != CacheType.ALL) { + sumCaches += historyOfType.getCount(); + } else { + allCaches = historyOfType.getCount(); + } + } + // check that sum of types equals 'all' + assertEquals(sumCaches, allCaches); + // check that two different routines behave the same + assertEquals(DataStore.getAllHistoryCachesCount(), sumCaches); + } + + public static void testCachedMissing() { + + // Tile to test + final Tile tile = new Tile(new Geopoint("N49 44.0 E8 37.0"), 14); + final Set tiles = new HashSet(); + tiles.add(tile); + + // set up geocaches to fill into cacheCache + final Geocache main = new Geocache(); + main.setGeocode("GC12345"); + main.setCoords(new Geopoint("N49 44.0 E8 37.0")); + final Geocache inTileLowZoom = new Geocache(); + inTileLowZoom.setGeocode("GC12346"); + inTileLowZoom.setCoords(new Geopoint("N49 44.001 E8 37.001"), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 5); + final Geocache outTile = new Geocache(); + outTile.setGeocode("GC12347"); + outTile.setCoords(new Geopoint(tile.getViewport().getLatitudeMin() - 0.1, tile.getViewport().getLongitudeMin() - 0.1)); + final Geocache otherConnector = new Geocache(); + otherConnector.setGeocode("OC0001"); + otherConnector.setCoords(new Geopoint("N49 44.0 E8 37.0")); + final Geocache inTileHighZoom = new Geocache(); + inTileHighZoom.setGeocode("GC12348"); + inTileHighZoom.setCoords(new Geopoint("N49 44.001 E8 37.001"), Tile.ZOOMLEVEL_MIN_PERSONALIZED + 1); + + // put in cache + DataStore.saveCache(main, EnumSet.of(SaveFlag.SAVE_CACHE)); + DataStore.saveCache(inTileLowZoom, EnumSet.of(SaveFlag.SAVE_CACHE)); + DataStore.saveCache(inTileHighZoom, EnumSet.of(SaveFlag.SAVE_CACHE)); + DataStore.saveCache(outTile, EnumSet.of(SaveFlag.SAVE_CACHE)); + DataStore.saveCache(otherConnector, EnumSet.of(SaveFlag.SAVE_CACHE)); + + final SearchResult search = new SearchResult(main); + + Set filteredGeoCodes = DataStore.getCachedMissingFromSearch(search, tiles, GCConnector.getInstance(), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1); + + assertTrue(filteredGeoCodes.contains(inTileLowZoom.getGeocode())); + assertFalse(filteredGeoCodes.contains(inTileHighZoom.getGeocode())); + assertFalse(filteredGeoCodes.contains(otherConnector.getGeocode())); + assertFalse(filteredGeoCodes.contains(outTile.getGeocode())); + assertFalse(filteredGeoCodes.contains(main.getGeocode())); + + } +} diff --git a/tests/src/cgeo/geocaching/StoredListTest.java b/tests/src/cgeo/geocaching/StoredListTest.java index dd8b6c7..ce7c963 100644 --- a/tests/src/cgeo/geocaching/StoredListTest.java +++ b/tests/src/cgeo/geocaching/StoredListTest.java @@ -5,13 +5,13 @@ import junit.framework.TestCase; public class StoredListTest extends TestCase { public static void testStandardListExists() { - final StoredList list = cgData.getList(StoredList.STANDARD_LIST_ID); + final StoredList list = DataStore.getList(StoredList.STANDARD_LIST_ID); assertNotNull(list); } public static void testEquals() { - final StoredList list1 = cgData.getList(StoredList.STANDARD_LIST_ID); - final StoredList list2 = cgData.getList(StoredList.STANDARD_LIST_ID); + final StoredList list1 = DataStore.getList(StoredList.STANDARD_LIST_ID); + final StoredList list2 = DataStore.getList(StoredList.STANDARD_LIST_ID); assertEquals(list1, list2); } diff --git a/tests/src/cgeo/geocaching/cgDataTest.java b/tests/src/cgeo/geocaching/cgDataTest.java deleted file mode 100644 index cacf061..0000000 --- a/tests/src/cgeo/geocaching/cgDataTest.java +++ /dev/null @@ -1,228 +0,0 @@ -package cgeo.geocaching; - -import cgeo.CGeoTestCase; -import cgeo.geocaching.connector.gc.GCConnector; -import cgeo.geocaching.connector.gc.Tile; -import cgeo.geocaching.enumerations.CacheType; -import cgeo.geocaching.enumerations.LoadFlags; -import cgeo.geocaching.enumerations.LoadFlags.SaveFlag; -import cgeo.geocaching.geopoint.Geopoint; -import cgeo.geocaching.geopoint.Viewport; - -import org.apache.commons.lang3.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.EnumSet; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -public class cgDataTest extends CGeoTestCase { - - public static void testStoredLists() { - - int listId1 = StoredList.STANDARD_LIST_ID; - int listId2 = StoredList.STANDARD_LIST_ID; - - // create caches - final Geocache cache1 = new Geocache(); - cache1.setGeocode("Cache 1"); - final Geocache cache2 = new Geocache(); - cache2.setGeocode("Cache 2"); - assertNotNull(cache2); - - try { - - // create lists - listId1 = cgData.createList("cgData Test"); - assertTrue(listId1 > StoredList.STANDARD_LIST_ID); - listId2 = cgData.createList("cgDataTest"); - assertTrue(listId2 > StoredList.STANDARD_LIST_ID); - assertTrue(cgData.getLists().size() >= 2); - - cache1.setDetailed(true); - cache1.setListId(listId1); - cache2.setDetailed(true); - cache2.setListId(listId1); - - // save caches to DB (cache1=listId1, cache2=listId1) - cgData.saveCache(cache1, LoadFlags.SAVE_ALL); - cgData.saveCache(cache2, LoadFlags.SAVE_ALL); - assertTrue(cgData.getAllCachesCount() >= 2); - - // rename list (cache1=listId1, cache2=listId1) - assertEquals(1, cgData.renameList(listId1, "cgData Test (renamed)")); - - // get list - final StoredList list1 = cgData.getList(listId1); - assertEquals("cgData Test (renamed)", list1.title); - - // move to list (cache1=listId2, cache2=listId2) - cgData.moveToList(Collections.singletonList(cache1), listId2); - assertEquals(1, cgData.getAllStoredCachesCount(CacheType.ALL, listId2)); - - // remove list (cache1=listId2, cache2=listId2) - assertTrue(cgData.removeList(listId1)); - - // mark dropped (cache1=1, cache2=0) - cgData.markDropped(Collections.singletonList(cache2)); - - // mark stored (cache1=1, cache2=listId2) - cgData.moveToList(Collections.singletonList(cache2), listId2); - assertEquals(2, cgData.getAllStoredCachesCount(CacheType.ALL, listId2)); - - // drop stored (cache1=0, cache2=0) - cgData.removeList(listId2); - - } finally { - - // remove caches - final Set geocodes = new HashSet(); - geocodes.add(cache1.getGeocode()); - geocodes.add(cache2.getGeocode()); - cgData.removeCaches(geocodes, LoadFlags.REMOVE_ALL); - - // remove list - cgData.removeList(listId1); - cgData.removeList(listId2); - } - } - - // Check that queries don't throw an exception (see issue #1429). - public static void testLoadWaypoints() { - final Viewport viewport = new Viewport(new Geopoint(-1, -2), new Geopoint(3, 4)); - cgData.loadWaypoints(viewport, false, false, CacheType.ALL); - cgData.loadWaypoints(viewport, false, true, CacheType.ALL); - cgData.loadWaypoints(viewport, true, false, CacheType.ALL); - cgData.loadWaypoints(viewport, true, true, CacheType.ALL); - cgData.loadWaypoints(viewport, false, false, CacheType.TRADITIONAL); - cgData.loadWaypoints(viewport, false, true, CacheType.TRADITIONAL); - cgData.loadWaypoints(viewport, true, false, CacheType.TRADITIONAL); - cgData.loadWaypoints(viewport, true, true, CacheType.TRADITIONAL); - } - - // Check that saving a cache and trackable without logs works (see #2199) - public static void testSaveWithoutLogs() { - - final String GEOCODE_CACHE = "TEST"; - - // create cache and trackable - final Geocache cache = new Geocache(); - cache.setGeocode(GEOCODE_CACHE); - cache.setDetailed(true); - final Trackable trackable = new Trackable(); - trackable.setLogs(null); - final List inventory = new ArrayList(); - inventory.add(trackable); - cache.setInventory(inventory); - - try { - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); - final Geocache loadedCache = cgData.loadCache(GEOCODE_CACHE, LoadFlags.LOAD_ALL_DB_ONLY); - assertNotNull("Cache was not saved!", loadedCache); - assertEquals(1, loadedCache.getInventory().size()); - } finally { - cgData.removeCache(GEOCODE_CACHE, LoadFlags.REMOVE_ALL); - } - } - - // Check that loading a cache by case insensitive geo code works correctly (see #3139) - public static void testGeocodeCaseInsensitive() { - - final String GEOCODE_CACHE = "TEST"; - final String upperCase = GEOCODE_CACHE; - final String lowerCase = StringUtils.lowerCase(upperCase); - assertFalse(upperCase.equals(lowerCase)); - - // create cache and trackable - final Geocache cache = new Geocache(); - cache.setGeocode(upperCase); - cache.setDetailed(true); - - try { - final Geocache oldCache = cgData.loadCache(upperCase, LoadFlags.LOAD_ALL_DB_ONLY); - assertNull("Database contained old cache!", oldCache); - - cgData.saveCache(cache, EnumSet.of(SaveFlag.SAVE_DB)); - final Geocache cacheWithOriginalCode = cgData.loadCache(upperCase, LoadFlags.LOAD_ALL_DB_ONLY); - assertNotNull("Cache was not saved correctly!", cacheWithOriginalCode); - - final Geocache cacheLowerCase = cgData.loadCache(lowerCase, LoadFlags.LOAD_ALL_DB_ONLY); - assertNotNull("Could not find cache by case insensitive geocode", cacheLowerCase); - - } finally { - cgData.removeCache(upperCase, LoadFlags.REMOVE_ALL); - } - } - - // Loading logs for an empty geocode should return an empty list, not null! - public static void testLoadLogsFromEmptyGeocode() { - - final List logs = cgData.loadLogs(""); - - assertNotNull("Logs must not be null", logs); - assertEquals("Logs from empty geocode must be empty", 0, logs.size()); - } - - public static void testLoadCacheHistory() { - int sumCaches = 0; - int allCaches = 0; - for (CacheType cacheType : CacheType.values()) { - SearchResult historyOfType = cgData.getHistoryOfCaches(false, cacheType); - assertNotNull(historyOfType); - if (cacheType != CacheType.ALL) { - sumCaches += historyOfType.getCount(); - } else { - allCaches = historyOfType.getCount(); - } - } - // check that sum of types equals 'all' - assertEquals(sumCaches, allCaches); - // check that two different routines behave the same - assertEquals(cgData.getAllHistoryCachesCount(), sumCaches); - } - - public static void testCachedMissing() { - - // Tile to test - final Tile tile = new Tile(new Geopoint("N49 44.0 E8 37.0"), 14); - final Set tiles = new HashSet(); - tiles.add(tile); - - // set up geocaches to fill into cacheCache - final Geocache main = new Geocache(); - main.setGeocode("GC12345"); - main.setCoords(new Geopoint("N49 44.0 E8 37.0")); - final Geocache inTileLowZoom = new Geocache(); - inTileLowZoom.setGeocode("GC12346"); - inTileLowZoom.setCoords(new Geopoint("N49 44.001 E8 37.001"), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 5); - final Geocache outTile = new Geocache(); - outTile.setGeocode("GC12347"); - outTile.setCoords(new Geopoint(tile.getViewport().getLatitudeMin() - 0.1, tile.getViewport().getLongitudeMin() - 0.1)); - final Geocache otherConnector = new Geocache(); - otherConnector.setGeocode("OC0001"); - otherConnector.setCoords(new Geopoint("N49 44.0 E8 37.0")); - final Geocache inTileHighZoom = new Geocache(); - inTileHighZoom.setGeocode("GC12348"); - inTileHighZoom.setCoords(new Geopoint("N49 44.001 E8 37.001"), Tile.ZOOMLEVEL_MIN_PERSONALIZED + 1); - - // put in cache - cgData.saveCache(main, EnumSet.of(SaveFlag.SAVE_CACHE)); - cgData.saveCache(inTileLowZoom, EnumSet.of(SaveFlag.SAVE_CACHE)); - cgData.saveCache(inTileHighZoom, EnumSet.of(SaveFlag.SAVE_CACHE)); - cgData.saveCache(outTile, EnumSet.of(SaveFlag.SAVE_CACHE)); - cgData.saveCache(otherConnector, EnumSet.of(SaveFlag.SAVE_CACHE)); - - final SearchResult search = new SearchResult(main); - - Set filteredGeoCodes = cgData.getCachedMissingFromSearch(search, tiles, GCConnector.getInstance(), Tile.ZOOMLEVEL_MIN_PERSONALIZED - 1); - - assertTrue(filteredGeoCodes.contains(inTileLowZoom.getGeocode())); - assertFalse(filteredGeoCodes.contains(inTileHighZoom.getGeocode())); - assertFalse(filteredGeoCodes.contains(otherConnector.getGeocode())); - assertFalse(filteredGeoCodes.contains(outTile.getGeocode())); - assertFalse(filteredGeoCodes.contains(main.getGeocode())); - - } -} diff --git a/tests/src/cgeo/geocaching/cgeoApplicationTest.java b/tests/src/cgeo/geocaching/cgeoApplicationTest.java index 83bf28d..4f45cc5 100644 --- a/tests/src/cgeo/geocaching/cgeoApplicationTest.java +++ b/tests/src/cgeo/geocaching/cgeoApplicationTest.java @@ -111,7 +111,7 @@ public class cgeoApplicationTest extends CGeoTestCase { if (Settings.isPremiumMember() || search.getError() == null) { assertEquals(1, search.getGeocodes().size()); assertTrue(search.getGeocodes().contains(geocode)); - return cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + return DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); } assertEquals(0, search.getGeocodes().size()); return null; @@ -295,7 +295,7 @@ public class cgeoApplicationTest extends CGeoTestCase { SearchResult search = ConnectorFactory.searchByViewport(viewport, tokens); assertNotNull(search); assertTrue(search.getGeocodes().contains(mockedCache.getGeocode())); - Geocache parsedCache = cgData.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); + Geocache parsedCache = DataStore.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); assertEquals(Settings.isPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords())); assertEquals(Settings.isPremiumMember(), parsedCache.isReliableLatLon()); @@ -307,7 +307,7 @@ public class cgeoApplicationTest extends CGeoTestCase { search = ConnectorFactory.searchByViewport(viewport, tokens); assertNotNull(search); assertTrue(search.getGeocodes().contains(mockedCache.getGeocode())); - parsedCache = cgData.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); + parsedCache = DataStore.loadCache(mockedCache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); assertEquals(Settings.isPremiumMember(), mockedCache.getCoords().equals(parsedCache.getCoords())); assertEquals(Settings.isPremiumMember(), parsedCache.isReliableLatLon()); @@ -350,7 +350,7 @@ public class cgeoApplicationTest extends CGeoTestCase { assertNotNull(search); assertTrue(search.getGeocodes().contains(cache.getGeocode())); // coords differ - final Geocache cacheFromViewport = cgData.loadCache(cache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cacheFromViewport = DataStore.loadCache(cache.getGeocode(), LoadFlags.LOAD_CACHE_OR_DB); Log.d("cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords expected = " + cache.getCoords()); Log.d("cgeoApplicationTest.testSearchByViewportNotLoggedIn: Coords actual = " + cacheFromViewport.getCoords()); assertFalse(cache.getCoords().isEqualTo(cacheFromViewport.getCoords(), 1e-3)); diff --git a/tests/src/cgeo/geocaching/connector/gc/WaypointsTest.java b/tests/src/cgeo/geocaching/connector/gc/WaypointsTest.java index d186526..19acd7c 100644 --- a/tests/src/cgeo/geocaching/connector/gc/WaypointsTest.java +++ b/tests/src/cgeo/geocaching/connector/gc/WaypointsTest.java @@ -1,9 +1,9 @@ package cgeo.geocaching.connector.gc; import cgeo.CGeoTestCase; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.utils.CancellableHandler; @@ -27,7 +27,7 @@ public class WaypointsTest extends CGeoTestCase { public static void testDownloadWaypoints() { // Check that repeated loads of "GC33HXE" hold the right number of waypoints (issue #2430). final String GEOCODE = "GC33HXE"; - cgData.removeCache(GEOCODE, LoadFlags.REMOVE_ALL); + DataStore.removeCache(GEOCODE, LoadFlags.REMOVE_ALL); assertEquals(9, downloadCache(GEOCODE).getWaypoints().size()); assertEquals(9, downloadCache(GEOCODE).getWaypoints().size()); } diff --git a/tests/src/cgeo/geocaching/connector/oc/OkapiClientTest.java b/tests/src/cgeo/geocaching/connector/oc/OkapiClientTest.java index aeb4e00..eb797c2 100644 --- a/tests/src/cgeo/geocaching/connector/oc/OkapiClientTest.java +++ b/tests/src/cgeo/geocaching/connector/oc/OkapiClientTest.java @@ -2,7 +2,7 @@ package cgeo.geocaching.connector.oc; import cgeo.CGeoTestCase; import cgeo.geocaching.Geocache; -import cgeo.geocaching.cgData; +import cgeo.geocaching.DataStore; import cgeo.geocaching.enumerations.LoadFlags; public class OkapiClientTest extends CGeoTestCase { @@ -15,7 +15,7 @@ public class OkapiClientTest extends CGeoTestCase { assertEquals("Oshkosh Municipal Tank", cache.getName()); assertTrue(cache.isDetailed()); // cache should be stored to DB (to listID 0) when loaded above - cache = cgData.loadCache(geoCode, LoadFlags.LOAD_ALL_DB_ONLY); + cache = DataStore.loadCache(geoCode, LoadFlags.LOAD_ALL_DB_ONLY); assertNotNull(cache); assertEquals(geoCode, cache.getGeocode()); assertEquals("Oshkosh Municipal Tank", cache.getName()); diff --git a/tests/src/cgeo/geocaching/export/ExportTest.java b/tests/src/cgeo/geocaching/export/ExportTest.java index 3e5505a..6d39f8d 100644 --- a/tests/src/cgeo/geocaching/export/ExportTest.java +++ b/tests/src/cgeo/geocaching/export/ExportTest.java @@ -1,9 +1,9 @@ package cgeo.geocaching.export; import cgeo.CGeoTestCase; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LogType; import cgeo.geocaching.geopoint.Geopoint; @@ -30,7 +30,7 @@ public class ExportTest extends CGeoTestCase { cache.setCoords(new Geopoint("N 49 44.000 E 8 37.000")); final LogEntry log = new LogEntry(1353244820000L, LogType.FOUND_IT, "Smile: \ud83d\ude0a"); cache.getLogs().add(log); - cgData.saveCache(cache, LoadFlags.SAVE_ALL); + DataStore.saveCache(cache, LoadFlags.SAVE_ALL); ArrayList exportList = new ArrayList(); exportList.add(cache); GpxExportTester gpxExport = new GpxExportTester(); @@ -38,7 +38,7 @@ public class ExportTest extends CGeoTestCase { try { result = gpxExport.testExportSync(exportList); } finally { - cgData.removeCache(cache.getGeocode(), LoadFlags.REMOVE_ALL); + DataStore.removeCache(cache.getGeocode(), LoadFlags.REMOVE_ALL); } assertNotNull(result); diff --git a/tests/src/cgeo/geocaching/files/GPXImporterTest.java b/tests/src/cgeo/geocaching/files/GPXImporterTest.java index 03f917c..8f5d821 100644 --- a/tests/src/cgeo/geocaching/files/GPXImporterTest.java +++ b/tests/src/cgeo/geocaching/files/GPXImporterTest.java @@ -1,8 +1,8 @@ package cgeo.geocaching.files; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.settings.Settings; @@ -74,7 +74,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertEquals(GPXImporter.IMPORT_STEP_FINISHED, iMsg.next().what); final SearchResult search = (SearchResult) importStepHandler.messages.get(3).obj; assertEquals(Collections.singletonList(geocode), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertTrue(cache.getWaypoints().isEmpty()); @@ -101,7 +101,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); final SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj; assertEquals(Collections.singletonList("GC31J2H"), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache("GC31J2H", LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertEquals(2, cache.getWaypoints().size()); } @@ -114,7 +114,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { runImportThread(importThread); assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); - final Geocache cache = cgData.loadCache("AID1", LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache("AID1", LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertEquals("First Aid Station #1", cache.getName()); } @@ -136,7 +136,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); final SearchResult search = (SearchResult) importStepHandler.messages.get(3).obj; assertEquals(Collections.singletonList("OC5952"), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache("OC5952", LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache("OC5952", LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); } @@ -178,7 +178,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); final SearchResult search = (SearchResult) importStepHandler.messages.get(3).obj; assertEquals(Collections.singletonList(geocode), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertTrue(cache.getWaypoints().isEmpty()); @@ -196,7 +196,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); final SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj; assertEquals(Collections.singletonList(geocode), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertEquals(1, cache.getWaypoints().size()); // this is the original pocket query result without test waypoint } @@ -222,7 +222,7 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { assertImportStepMessages(GPXImporter.IMPORT_STEP_START, GPXImporter.IMPORT_STEP_READ_FILE, GPXImporter.IMPORT_STEP_READ_WPT_FILE, GPXImporter.IMPORT_STEP_STORE_STATIC_MAPS, GPXImporter.IMPORT_STEP_FINISHED); final SearchResult search = (SearchResult) importStepHandler.messages.get(4).obj; assertEquals(Collections.singletonList(geocode), new ArrayList(search.getGeocodes())); - final Geocache cache = cgData.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); + final Geocache cache = DataStore.loadCache(geocode, LoadFlags.LOAD_CACHE_OR_DB); assertCacheProperties(cache); assertEquals(1, cache.getWaypoints().size()); // this is the original pocket query result without test waypoint } @@ -267,8 +267,8 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { tempDir.mkdir(); assertTrue("Could not create directory " + tempDir.getPath(), tempDir.exists()); // workaround to get storage initialized - cgData.getAllHistoryCachesCount(); - listId = cgData.createList("cgeogpxesTest"); + DataStore.getAllHistoryCachesCount(); + listId = DataStore.createList("cgeogpxesTest"); importCacheStaticMaps = Settings.isStoreOfflineMaps(); TestSettings.setStoreOfflineMaps(true); @@ -278,11 +278,11 @@ public class GPXImporterTest extends AbstractResourceInstrumentationTestCase { @Override protected void tearDown() throws Exception { - final SearchResult search = cgData.getBatchOfStoredCaches(null, CacheType.ALL, listId); + final SearchResult search = DataStore.getBatchOfStoredCaches(null, CacheType.ALL, listId); final List cachesInList = new ArrayList(); cachesInList.addAll(search.getCachesFromSearchResult(LoadFlags.LOAD_CACHE_OR_DB)); - cgData.markDropped(cachesInList); - cgData.removeList(listId); + DataStore.markDropped(cachesInList); + DataStore.removeList(listId); deleteDirectory(tempDir); TestSettings.setStoreOfflineMaps(importCacheStaticMaps); TestSettings.setStoreOfflineWpMaps(importWpStaticMaps); diff --git a/tests/src/cgeo/geocaching/files/GPXParserTest.java b/tests/src/cgeo/geocaching/files/GPXParserTest.java index 06661eb..9604519 100644 --- a/tests/src/cgeo/geocaching/files/GPXParserTest.java +++ b/tests/src/cgeo/geocaching/files/GPXParserTest.java @@ -1,9 +1,9 @@ package cgeo.geocaching.files; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.LogEntry; import cgeo.geocaching.Waypoint; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheSize; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; @@ -215,7 +215,7 @@ public class GPXParserTest extends AbstractResourceInstrumentationTestCase { } } // reload caches, because the parser only returns the minimum version of each cache - return new ArrayList(cgData.loadCaches(result, LoadFlags.LOAD_ALL_DB_ONLY)); + return new ArrayList(DataStore.loadCaches(result, LoadFlags.LOAD_ALL_DB_ONLY)); } public static void testParseDateWithFractionalSeconds() throws ParseException { @@ -258,9 +258,9 @@ public class GPXParserTest extends AbstractResourceInstrumentationTestCase { removeCacheCompletely(geocode); final List caches = readGPX10(R.raw.lazy); assertEquals(1, caches.size()); - cgData.removeAllFromCache(); + DataStore.removeAllFromCache(); // load only the minimum cache, it has several members missing - final Geocache minimalCache = cgData.loadCache(geocode, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); + final Geocache minimalCache = DataStore.loadCache(geocode, EnumSet.of(LoadFlag.LOAD_DB_MINIMAL)); // now check that we load lazy members on demand assertFalse(minimalCache.getAttributes().isEmpty()); diff --git a/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java index cb8238f..bb03274 100644 --- a/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java +++ b/tests/src/cgeo/geocaching/test/AbstractResourceInstrumentationTestCase.java @@ -1,9 +1,9 @@ package cgeo.geocaching.test; +import cgeo.geocaching.DataStore; import cgeo.geocaching.Geocache; import cgeo.geocaching.SearchResult; import cgeo.geocaching.StoredList; -import cgeo.geocaching.cgData; import cgeo.geocaching.enumerations.CacheType; import cgeo.geocaching.enumerations.LoadFlags; import cgeo.geocaching.enumerations.LoadFlags.RemoveFlag; @@ -27,7 +27,7 @@ public abstract class AbstractResourceInstrumentationTestCase extends Instrument protected static void removeCacheCompletely(final String geocode) { final EnumSet flags = EnumSet.copyOf(LoadFlags.REMOVE_ALL); flags.add(RemoveFlag.REMOVE_OWN_WAYPOINTS_ONLY_FOR_TESTING); - cgData.removeCache(geocode, flags); + DataStore.removeCache(geocode, flags); } protected InputStream getResourceStream(int resourceId) { @@ -65,17 +65,17 @@ public abstract class AbstractResourceInstrumentationTestCase extends Instrument @Override protected void setUp() throws Exception { super.setUp(); - temporaryListId = cgData.createList("Temporary unit testing"); + temporaryListId = DataStore.createList("Temporary unit testing"); assertTrue(temporaryListId != StoredList.TEMPORARY_LIST_ID); assertTrue(temporaryListId != StoredList.STANDARD_LIST_ID); } @Override protected void tearDown() throws Exception { - final SearchResult search = cgData.getBatchOfStoredCaches(null, CacheType.ALL, temporaryListId); + final SearchResult search = DataStore.getBatchOfStoredCaches(null, CacheType.ALL, temporaryListId); assertNotNull(search); - cgData.removeCaches(search.getGeocodes(), LoadFlags.REMOVE_ALL); - cgData.removeList(temporaryListId); + DataStore.removeCaches(search.getGeocodes(), LoadFlags.REMOVE_ALL); + DataStore.removeList(temporaryListId); super.tearDown(); } -- cgit v1.1