package com.mapbox.mapboxsdk.offline;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;
import android.util.Log;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.exceptions.OfflineDatabaseException;
import java.util.Date;
public class OfflineMapDatabase implements MapboxConstants {
private static final String TAG = "OfflineMapDatabase";
private Context context;
private SQLiteDatabase db;
private String uniqueID;
private String mapID;
private boolean includesMetadata;
private boolean includesMarkers;
private RasterImageQuality imageQuality;
private String path;
private boolean invalid;
private boolean initializedProperly = false;
/**
* Default Constructor
*
* @param context Context of Android app
*/
public OfflineMapDatabase(Context context) {
super();
this.context = context;
}
/**
* Constructor
* @param context Context of Android app
* @param mapID MapId
*/
public OfflineMapDatabase(Context context, String mapID) {
super();
this.context = context;
this.mapID = mapID;
}
public String getUniqueID() {
return uniqueID;
}
public String getMapID() {
return mapID;
}
public String getPath() {
return path;
}
public RasterImageQuality getImageQuality() {
return imageQuality;
}
public boolean initializeDatabase() {
String uniqueID = sqliteMetadataForName("uniqueID");
String mapID = sqliteMetadataForName("mapID");
String includesMetadata = sqliteMetadataForName("includesMetadata");
String includesMarkers = sqliteMetadataForName("includesMarkers");
String imageQuality = sqliteMetadataForName("imageQuality");
if (TextUtils.isEmpty(uniqueID)) {
uniqueID = String.format(MAPBOX_LOCALE, "%s-%d", mapID, new Date().getTime() / 1000L);
}
if (!TextUtils.isEmpty(mapID) && !TextUtils.isEmpty(includesMetadata) && !TextUtils.isEmpty(includesMarkers) && !TextUtils.isEmpty(imageQuality)) {
// Reaching this point means that the specified database file at path pointed to an sqlite file which had
// all the required values in its metadata table. That means the file passed the test for being a valid
// offline map database.
//
this.uniqueID = uniqueID;
this.mapID = mapID;
this.includesMetadata = "YES".equalsIgnoreCase(includesMetadata);
this.includesMarkers = "YES".equalsIgnoreCase(includesMarkers);
this.imageQuality = RasterImageQuality.getEnumForValue(Integer.parseInt(imageQuality));
SQLiteDatabase db = database();
this.path = db.getPath();
this.initializedProperly = true;
} else {
// Reaching this point means the file at path isn't a valid offline map database, so we can't use it.
Log.w(TAG, "Invalid offline map database. Can't be used.");
}
return initializedProperly;
}
public byte[] dataForURL(String url) throws OfflineDatabaseException {
byte[] data = sqliteDataForURL(url);
/*
if (data == null || data.length == 0) {
String reason = String.format("The offline database has no data for %s", url);
throw new OfflineDatabaseException(reason);
}
*/
return data;
}
public void invalidate() {
this.invalid = false;
}
public String sqliteMetadataForName(String name) {
if (mapID == null) {
return null;
}
SQLiteDatabase db = database();
if (db == null) {
return null;
}
String query = "SELECT " + OfflineDatabaseHandler.FIELD_METADATA_VALUE + " FROM " + OfflineDatabaseHandler.TABLE_METADATA + " WHERE " + OfflineDatabaseHandler.FIELD_METADATA_NAME + "=?;";
String[] selectionArgs = new String[] { name };
Cursor cursor = db.rawQuery(query, selectionArgs);
if (cursor == null) {
return null;
}
String res = null;
if (cursor.moveToFirst()) {
res = cursor.getString(cursor.getColumnIndex(OfflineDatabaseHandler.FIELD_METADATA_VALUE));
}
cursor.close();
return res;
}
public byte[] sqliteDataForURL(String url) {
if (mapID == null) {
return null;
}
SQLiteDatabase db = database();
if (db == null) {
return null;
}
String query = "SELECT " + OfflineDatabaseHandler.FIELD_RESOURCES_DATA + " FROM " + OfflineDatabaseHandler.TABLE_RESOURCES + " WHERE " + OfflineDatabaseHandler.FIELD_RESOURCES_URL + "=?;";
String[] selectionArgs = new String[] { url };
Cursor cursor = db.rawQuery(query, selectionArgs);
if (cursor == null) {
return null;
}
byte[] res = null;
if (cursor.moveToFirst()) {
res = cursor.getBlob(cursor.getColumnIndex(OfflineDatabaseHandler.FIELD_RESOURCES_DATA));
}
cursor.close();
return res;
}
private SQLiteDatabase database() {
if (db == null) {
db = OfflineDatabaseManager.getOfflineDatabaseManager(context).getOfflineDatabaseHandlerForMapId(mapID).getReadableDatabase();
}
if (!db.isOpen()) {
db = null;
}
return db;
}
public void closeDatabase() {
if (db != null && db.isOpen()) {
db.close();
}
db = null;
}
}