/*
* TV-Browser for Android
* Copyright (C) 2013 René Mach (rene@tvbrowser.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to use, copy, modify or merge the Software,
* furthermore to publish and distribute the Software free of charge without modifications and to
* permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.tvbrowser.content;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Set;
import java.util.TimeZone;
import org.tvbrowser.tvbrowser.R;
import org.tvbrowser.utils.IOUtils;
import org.tvbrowser.utils.PrefUtils;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.content.SharedPreferences;
import android.content.UriMatcher;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteDatabaseLockedException;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
public class TvBrowserContentProvider extends ContentProvider {
public static final String DATABASE_TVB_NAME = "tvbrowser.db";
public static final String AUTHORITY = "org.tvbrowser.tvbrowsercontentprovider";
public static final Uri CONTENT_URI_GROUPS = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/groups");
public static final Uri CONTENT_URI_CHANNELS = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/channels");
public static final Uri CONTENT_URI_CHANNELS_WITH_GROUP = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/channelgroups");
public static final Uri CONTENT_URI_DATA = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/data");
public static final Uri RAW_QUERY_CONTENT_URI_DATA = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/rawdata");
public static final Uri CONTENT_URI_DATA_UPDATE = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/dataupdate");
public static final Uri CONTENT_URI_DATA_WITH_CHANNEL = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/datachannels");
public static final Uri CONTENT_URI_DATA_VERSION = Uri.parse("content://org.tvbrowser.tvbrowsercontentprovider/dataversion");
public static final String KEY_ID = "_id";
public static boolean INFORM_FOR_CHANGES = true;
private TvBrowserDataBaseHelper mDataBaseHelper;
private static final int GROUPS = 1;
private static final int GROUP_ID = 2;
private static final int CHANNELS = 10;
private static final int CHANNEL_ID = 11;
private static final int CHANNELGROUPS = 12;
private static final int CHANNELGROUPS_ID = 13;
private static final int DATA = 20;
private static final int DATA_ID = 21;
private static final int RAW_DATA = 22;
private static final int RAW_DATA_ID = 23;
private static final int DATA_CHANNELS = 30;
private static final int DATA_CHANNEL_ID = 31;
private static final int DATA_UPDATE = 40;
private static final int DATA_UPDATE_ID = 41;
private static final int DATA_VERSION = 50;
private static final int DATA_VERSION_ID = 51;
private static final int SEARCH = 100;
private static final HashMap<String,String> SEARCH_PROJECTION_MAP;
// column name for CONCAT raw queries
public static final String CONCAT_TABLE_PLACE_HOLDER = "concatTablePlaceHolder";
public static final String CONCAT_RAW_KEY = "concatRawQueryColumn";
// Column names for group table
public static final String GROUP_KEY_DATA_SERVICE_ID = "dataServiceID";
public static final String GROUP_KEY_GROUP_ID = "groupID";
public static final String GROUP_KEY_GROUP_NAME = "groupName";
public static final String GROUP_KEY_GROUP_PROVIDER = "groupProvider";
public static final String GROUP_KEY_GROUP_DESCRIPTION = "groupDescription";
public static final String GROUP_KEY_GROUP_MIRRORS = "groupMirrors";
public static final String GROUP_KEY_GROUP_MIRRORS_DEFAULT = "groupDefaultMirrors";
// Column names for the channel table
public static final String CHANNEL_KEY_BASE_COUNTRY = "baseCountry";
public static final String CHANNEL_KEY_TIMEZONE = "timeZone";
public static final String CHANNEL_KEY_CHANNEL_ID = "channelID";
public static final String CHANNEL_KEY_NAME = "name";
public static final String CHANNEL_KEY_COPYRIGHT = "copyright";
public static final String CHANNEL_KEY_WEBSITE = "website";
public static final String CHANNEL_KEY_LOGO_URL = "logoURL";
public static final String CHANNEL_KEY_LOGO = "logo";
public static final String CHANNEL_KEY_CATEGORY = "category";
public static final String CHANNEL_KEY_FULL_NAME = "fullName";
public static final String CHANNEL_KEY_ALL_COUNTRIES = "allCountries";
public static final String CHANNEL_KEY_JOINED_CHANNEL_ID = "joinedChannelID";
public static final String CHANNEL_KEY_ORDER_NUMBER = "orderNumber";
public static final String CHANNEL_KEY_SELECTION = "isSelected";
public static final String CHANNEL_KEY_USER_CHANNEL_NAME = "userChannelName";
public static final String CHANNEL_KEY_USER_ICON = "userChannelIcon";
public static final String CHANNEL_KEY_USER_START_TIME = "userStartTime";
public static final String CHANNEL_KEY_USER_END_TIME = "userEndTime";
// Column names for the data table
public static final String DATA_KEY_STARTTIME = "startTime";
public static final String DATA_KEY_ENDTIME = "endTime";
public static final String DATA_KEY_TITLE = "title";
public static final String DATA_KEY_TITLE_ORIGINAL = "titleOriginal";
public static final String DATA_KEY_EPISODE_TITLE = "episodeTitle";
public static final String DATA_KEY_EPISODE_TITLE_ORIGINAL = "episodeTitleOriginal";
public static final String DATA_KEY_SHORT_DESCRIPTION = "shortDescription";
public static final String DATA_KEY_DESCRIPTION = "description";
public static final String DATA_KEY_ACTORS = "actors";
public static final String DATA_KEY_REGIE = "regie";
public static final String DATA_KEY_CUSTOM_INFO = "customInfo";
public static final String DATA_KEY_CATEGORIES = "categories";
public static final String DATA_KEY_AGE_LIMIT = "ageLimit";
public static final String DATA_KEY_WEBSITE_LINK = "websiteLink";
public static final String DATA_KEY_GENRE = "genre";
public static final String DATA_KEY_ORIGIN = "origin";
public static final String DATA_KEY_NETTO_PLAY_TIME = "nettoPlayTime";
public static final String DATA_KEY_VPS = "vps";
public static final String DATA_KEY_SCRIPT = "script";
public static final String DATA_KEY_REPETITION_FROM = "repetitionFrom";
public static final String DATA_KEY_MUSIC = "music";
public static final String DATA_KEY_MODERATION = "moderation";
public static final String DATA_KEY_YEAR = "year";
public static final String DATA_KEY_REPETITION_ON = "repetitionOn";
public static final String DATA_KEY_PICTURE = "picture";
public static final String DATA_KEY_PICTURE_COPYRIGHT = "pictureCopyright";
public static final String DATA_KEY_PICTURE_DESCRIPTION = "pictureDescription";
public static final String DATA_KEY_EPISODE_NUMBER = "episodeNumber";
public static final String DATA_KEY_EPISODE_COUNT = "episodeCount";
public static final String DATA_KEY_SEASON_NUMBER = "seasonNumber";
public static final String DATA_KEY_PRODUCER = "producer";
public static final String DATA_KEY_CAMERA = "camera";
public static final String DATA_KEY_CUT = "cut";
public static final String DATA_KEY_OTHER_PERSONS = "otherPersons";
public static final String DATA_KEY_RATING = "rating";
public static final String DATA_KEY_PRODUCTION_FIRM = "productionFirm";
public static final String DATA_KEY_AGE_LIMIT_STRING = "ageLimitString";
public static final String DATA_KEY_LAST_PRODUCTION_YEAR = "lastProductionYear";
public static final String DATA_KEY_ADDITIONAL_INFO = "additionalInfo";
public static final String DATA_KEY_SERIES = "series";
public static final String DATA_KEY_UNIX_DATE = "unixDate";
public static final String DATA_KEY_DATE_PROG_ID = "dateProgID";
public static final String DATA_KEY_DATE_PROG_STRING_ID = "dateProgStringID";
public static final String DATA_KEY_DONT_WANT_TO_SEE = "dontWantToSee";
public static final String DATA_KEY_REMOVED_REMINDER = "removedReminder";
public static final String DATA_KEY_MARKING_MARKING = "markingMarking";
public static final String DATA_KEY_MARKING_FAVORITE = "markingFavorite";
public static final String DATA_KEY_MARKING_FAVORITE_REMINDER = "markingFavoriteReminder";
public static final String DATA_KEY_MARKING_REMINDER = "markingReminder";
public static final String DATA_KEY_MARKING_SYNC = "markingSync";
public static final String DATA_KEY_REMOVED_SYNC = "removedSync";
public static final String DATA_KEY_UTC_START_MINUTE_AFTER_MIDNIGHT = "utcStartMinuteAfterMidnight";
public static final String DATA_KEY_UTC_END_MINUTE_AFTER_MIDNIGHT = "utcEndMinuteAfterMidnight";
public static final String DATA_KEY_DURATION_IN_MINUTES = "durationInMinutes";
public static final String DATA_KEY_INFO_BLACK_AND_WHITE = "infoBlackAndWhite";
public static final String DATA_KEY_INFO_4_TO_3 = "infoFourToThree";
public static final String DATA_KEY_INFO_16_TO_9 = "infoSixteenToNine";
public static final String DATA_KEY_INFO_MONO = "infoMono";
public static final String DATA_KEY_INFO_STEREO = "infoStereo";
public static final String DATA_KEY_INFO_DOLBY_SOURROUND = "infoDoblySourround";
public static final String DATA_KEY_INFO_DOLBY_DIGITAL_5_1 = "infoDigitalFivePointOne";
public static final String DATA_KEY_INFO_SECOND_AUDIO_PROGRAM = "infoSecondAudioProgram";
public static final String DATA_KEY_INFO_CLOSED_CAPTION = "infoClosedCaption";
public static final String DATA_KEY_INFO_LIVE = "infoLive";
public static final String DATA_KEY_INFO_OMU = "infoOmU";
public static final String DATA_KEY_INFO_FILM = "infoFilm";
public static final String DATA_KEY_INFO_SERIES = "infoSeries";
public static final String DATA_KEY_INFO_NEW = "infoNew";
public static final String DATA_KEY_INFO_AUDIO_DESCRIPTION = "infoAudioDescritption";
public static final String DATA_KEY_INFO_NEWS = "infoNews";
public static final String DATA_KEY_INFO_SHOW = "infoShow";
public static final String DATA_KEY_INFO_MAGAZIN = "infoMagazin";
public static final String DATA_KEY_INFO_HD = "infoHD";
public static final String DATA_KEY_INFO_DOCUMENTATION = "infoDocumentation";
public static final String DATA_KEY_INFO_ART = "infoArt";
public static final String DATA_KEY_INFO_SPORT = "infoSport";
public static final String DATA_KEY_INFO_CHILDREN = "infoChildren";
public static final String DATA_KEY_INFO_OTHER = "infoOther";
public static final String DATA_KEY_INFO_SIGN_LANGUAGE = "infoSingLanguage";
private static final HashMap<String, String> MAP_DATA_KEY_TYPE = createDataKeyTypeMap();
private static HashMap<String, String> createDataKeyTypeMap () {
final HashMap<String, String> mapDataKeyType = new HashMap<String, String>();
mapDataKeyType.put(DATA_KEY_STARTTIME ," INTEGER NOT NULL");
mapDataKeyType.put(DATA_KEY_ENDTIME ," INTEGER NOT NULL");
mapDataKeyType.put(DATA_KEY_TITLE ," TEXT NOT NULL");
mapDataKeyType.put(DATA_KEY_SHORT_DESCRIPTION ," TEXT");
mapDataKeyType.put(DATA_KEY_DESCRIPTION ," TEXT");
mapDataKeyType.put(DATA_KEY_TITLE_ORIGINAL ," TEXT");
mapDataKeyType.put(DATA_KEY_EPISODE_TITLE ," TEXT");
mapDataKeyType.put(DATA_KEY_EPISODE_TITLE_ORIGINAL ," TEXT");
mapDataKeyType.put(DATA_KEY_ACTORS ," TEXT");
mapDataKeyType.put(DATA_KEY_REGIE ," TEXT");
mapDataKeyType.put(DATA_KEY_CUSTOM_INFO ," TEXT");
mapDataKeyType.put(DATA_KEY_CATEGORIES ," INTEGER");
mapDataKeyType.put(DATA_KEY_AGE_LIMIT ," INTEGER");
mapDataKeyType.put(DATA_KEY_WEBSITE_LINK," TEXT");
mapDataKeyType.put(DATA_KEY_GENRE ," TEXT");
mapDataKeyType.put(DATA_KEY_ORIGIN ," TEXT");
mapDataKeyType.put(DATA_KEY_NETTO_PLAY_TIME ," INTEGER");
mapDataKeyType.put(DATA_KEY_VPS ," INTEGER");
mapDataKeyType.put(DATA_KEY_SCRIPT ," TEXT");
mapDataKeyType.put(DATA_KEY_REPETITION_FROM ," TEXT");
mapDataKeyType.put(DATA_KEY_REPETITION_ON ," TEXT");
mapDataKeyType.put(DATA_KEY_MUSIC ," TEXT");
mapDataKeyType.put(DATA_KEY_MODERATION ," TEXT");
mapDataKeyType.put(DATA_KEY_YEAR ," INTEGER");
mapDataKeyType.put(DATA_KEY_PICTURE ," BLOB");
mapDataKeyType.put(DATA_KEY_PICTURE_COPYRIGHT ," TEXT");
mapDataKeyType.put(DATA_KEY_PICTURE_DESCRIPTION ," TEXT");
mapDataKeyType.put(DATA_KEY_EPISODE_NUMBER ," INTEGER");
mapDataKeyType.put(DATA_KEY_EPISODE_COUNT ," INTEGER");
mapDataKeyType.put(DATA_KEY_SEASON_NUMBER ," INTEGER");
mapDataKeyType.put(DATA_KEY_PRODUCER ," TEXT");
mapDataKeyType.put(DATA_KEY_CAMERA ," TEXT");
mapDataKeyType.put(DATA_KEY_CUT ," TEXT");
mapDataKeyType.put(DATA_KEY_OTHER_PERSONS ," TEXT");
mapDataKeyType.put(DATA_KEY_RATING ," INTEGER");
mapDataKeyType.put(DATA_KEY_PRODUCTION_FIRM ," TEXT");
mapDataKeyType.put(DATA_KEY_AGE_LIMIT_STRING," TEXT");
mapDataKeyType.put(DATA_KEY_LAST_PRODUCTION_YEAR ," INTEGER");
mapDataKeyType.put(DATA_KEY_ADDITIONAL_INFO ," TEXT");
mapDataKeyType.put(DATA_KEY_SERIES ," TEXT");
mapDataKeyType.put(DATA_KEY_UNIX_DATE ," INTEGER");
mapDataKeyType.put(DATA_KEY_DATE_PROG_ID ," INTEGER");
mapDataKeyType.put(DATA_KEY_DATE_PROG_STRING_ID ," TEXT");
mapDataKeyType.put(DATA_KEY_DONT_WANT_TO_SEE ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_REMOVED_REMINDER ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_MARKING_MARKING ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_MARKING_FAVORITE ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_MARKING_FAVORITE_REMINDER ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_MARKING_REMINDER ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_MARKING_SYNC ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_REMOVED_SYNC ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_UTC_START_MINUTE_AFTER_MIDNIGHT ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_UTC_END_MINUTE_AFTER_MIDNIGHT ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_DURATION_IN_MINUTES ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_BLACK_AND_WHITE ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_4_TO_3 ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_16_TO_9 ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_MONO ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_STEREO ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_DOLBY_SOURROUND ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_DOLBY_DIGITAL_5_1 ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_SECOND_AUDIO_PROGRAM ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_CLOSED_CAPTION ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_LIVE ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_OMU ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_FILM ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_SERIES ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_NEW ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_AUDIO_DESCRIPTION ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_NEWS ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_SHOW ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_MAGAZIN ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_HD ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_DOCUMENTATION ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_ART ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_SPORT ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_CHILDREN ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_OTHER ," INTEGER DEFAULT 0");
mapDataKeyType.put(DATA_KEY_INFO_SIGN_LANGUAGE ," INTEGER DEFAULT 0 ");
return mapDataKeyType;
}
// Artificial key for creating column at selection
public static final String DATA_KEY_START_DAY_LOCAL = "startDayLocal";
public static final String[] INFO_CATEGORIES_COLUMNS_ARRAY = {
DATA_KEY_INFO_BLACK_AND_WHITE,
DATA_KEY_INFO_4_TO_3,
DATA_KEY_INFO_16_TO_9,
DATA_KEY_INFO_MONO,
DATA_KEY_INFO_STEREO,
DATA_KEY_INFO_DOLBY_SOURROUND,
DATA_KEY_INFO_DOLBY_DIGITAL_5_1,
DATA_KEY_INFO_SECOND_AUDIO_PROGRAM,
DATA_KEY_INFO_CLOSED_CAPTION,
DATA_KEY_INFO_LIVE,
DATA_KEY_INFO_OMU,
DATA_KEY_INFO_FILM,
DATA_KEY_INFO_SERIES,
DATA_KEY_INFO_NEW,
DATA_KEY_INFO_AUDIO_DESCRIPTION,
DATA_KEY_INFO_NEWS,
DATA_KEY_INFO_SHOW,
DATA_KEY_INFO_MAGAZIN,
DATA_KEY_INFO_HD,
DATA_KEY_INFO_DOCUMENTATION,
DATA_KEY_INFO_ART,
DATA_KEY_INFO_SPORT,
DATA_KEY_INFO_CHILDREN,
DATA_KEY_INFO_OTHER,
DATA_KEY_INFO_SIGN_LANGUAGE
};
public static final String[] TEXT_SEARCHABLE_COLUMN_ARRAY = {
DATA_KEY_ACTORS,
DATA_KEY_ADDITIONAL_INFO,
DATA_KEY_CAMERA,
DATA_KEY_CUSTOM_INFO,
DATA_KEY_CUT,
DATA_KEY_DESCRIPTION,
DATA_KEY_EPISODE_TITLE,
DATA_KEY_EPISODE_TITLE_ORIGINAL,
DATA_KEY_GENRE,
DATA_KEY_MODERATION,
DATA_KEY_MUSIC,
DATA_KEY_ORIGIN,
DATA_KEY_OTHER_PERSONS,
DATA_KEY_PICTURE_DESCRIPTION,
DATA_KEY_PRODUCER,
DATA_KEY_PRODUCTION_FIRM,
DATA_KEY_REGIE,
DATA_KEY_SCRIPT,
DATA_KEY_SERIES,
DATA_KEY_SHORT_DESCRIPTION,
DATA_KEY_TITLE,
DATA_KEY_TITLE_ORIGINAL
};
// Column names for data version table
public static final String VERSION_KEY_DAYS_SINCE_1970 = "daysSince1970";
public static final String VERSION_KEY_BASE_VERSION = "baseVersion";
public static final String VERSION_KEY_MORE0016_VERSION = "more0016Version";
public static final String VERSION_KEY_MORE1600_VERSION = "more1600Version";
public static final String VERSION_KEY_PICTURE0016_VERSION = "picture0016Version";
public static final String VERSION_KEY_PICTURE1600_VERSION = "picture1600Version";
public static final String[] MARKING_COLUMNS = {
DATA_KEY_MARKING_MARKING,
DATA_KEY_MARKING_FAVORITE,
DATA_KEY_MARKING_FAVORITE_REMINDER,
DATA_KEY_MARKING_REMINDER,
DATA_KEY_MARKING_SYNC,
DATA_KEY_DONT_WANT_TO_SEE
};
static {
SEARCH_PROJECTION_MAP = new HashMap<String, String>();
SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1, DATA_KEY_TITLE + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1);
SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_2, DATA_KEY_EPISODE_TITLE + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2);
SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID,KEY_ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID);
SEARCH_PROJECTION_MAP.put("_id", KEY_ID + " AS " + "_id");
}
private static final UriMatcher uriMatcher;
// Allocate the UriMatcher object, where a URI ending in 'earthquakes' will correspond to a request
// for all eathquakes, and 'earthquakes' with a traisling '/[rowID]' will represent a single earthquake row.
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "groups", GROUPS);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "groups/#", GROUP_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "channels", CHANNELS);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "channels/#", CHANNEL_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "channelgroups", CHANNELGROUPS);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "channelgroups/#", CHANNELGROUPS_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "data", DATA);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "data/#", DATA_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "rawdata", RAW_DATA);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "rawdata/#", RAW_DATA_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "dataupdate", DATA_UPDATE);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "dataupdate/#", DATA_UPDATE_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "datachannels", DATA_CHANNELS);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "datachannels/#", DATA_CHANNEL_ID);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", SearchManager.SUGGEST_URI_PATH_SHORTCUT, SEARCH);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", SearchManager.SUGGEST_URI_PATH_SHORTCUT + "/*", SEARCH);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "dataversion", DATA_VERSION);
uriMatcher.addURI("org.tvbrowser.tvbrowsercontentprovider", "dataversion/#", DATA_VERSION_ID);
}
public static final String[] getColumnArrayWithMarkingColums(String... columns) {
String[] projection = new String[columns.length + TvBrowserContentProvider.MARKING_COLUMNS.length];
System.arraycopy(TvBrowserContentProvider.MARKING_COLUMNS, 0, projection, 0, TvBrowserContentProvider.MARKING_COLUMNS.length);
System.arraycopy(columns, 0, projection, TvBrowserContentProvider.MARKING_COLUMNS.length, columns.length);
return projection;
}
@Override
public int delete(Uri uri, String where, String[] whereArgs) {
int count = 0;
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
boolean data_with_channel = false;
switch(uriMatcher.match(uri)) {
case GROUPS: count = database.delete(TvBrowserDataBaseHelper.GROUPS_TABLE, where, whereArgs);break;
case GROUP_ID: {String segment = uri.getPathSegments().get(1);
count = database.delete(TvBrowserDataBaseHelper.GROUPS_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case CHANNELS: count = database.delete(CHANNEL_TABLE, where, whereArgs);break;
case CHANNEL_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.delete(CHANNEL_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA: count = database.delete(TvBrowserDataBaseHelper.DATA_TABLE, where, whereArgs);break;
case DATA_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.delete(TvBrowserDataBaseHelper.DATA_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA_UPDATE: count = database.delete(TvBrowserDataBaseHelper.DATA_TABLE, where, whereArgs);break;
case DATA_UPDATE_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.delete(TvBrowserDataBaseHelper.DATA_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA_VERSION: count = database.delete(TvBrowserDataBaseHelper.VERSION_TABLE, where, whereArgs);break;
case DATA_VERSION_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.delete(TvBrowserDataBaseHelper.VERSION_TABLE, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
default: throw new IllegalArgumentException("Unsupported URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
if(data_with_channel) {
getContext().getContentResolver().notifyChange(CONTENT_URI_DATA_WITH_CHANNEL, null);
}
}
return count;
}
@Override
public String getType(Uri uri) {
switch(uriMatcher.match(uri)) {
case GROUPS: return "vnd.andorid.cursor.dir/vnd.tvbrowser.groups";
case GROUP_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.groups";
case CHANNELS: return "vnd.andorid.cursor.dir/vnd.tvbrowser.channels";
case CHANNEL_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.channels";
case DATA: return "vnd.andorid.cursor.dir/vnd.tvbrowser.data";
case DATA_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.data";
case RAW_DATA: return "vnd.andorid.cursor.dir/vnd.tvbrowser.rawdata";
case RAW_DATA_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.rawdata";
case DATA_UPDATE: return "vnd.andorid.cursor.dir/vnd.tvbrowser.dataupdate";
case DATA_UPDATE_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.dataupdate";
case DATA_CHANNELS: return "vnd.andorid.cursor.dir/vnd.tvbrowser.datachannels";
case DATA_CHANNEL_ID: return "vnd.andorid.cursor.item/vnd.tvbrowser.datachannels";
case SEARCH: return SearchManager.SUGGEST_MIME_TYPE;
default: throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if(IOUtils.isDatabaseAccessible(getContext())) {
switch(uriMatcher.match(uri)) {
case GROUPS: return insertGroup(uri, values);
case CHANNELS: return insertChannel(uri, values);
case DATA: return insertData(uri, values);
case DATA_UPDATE: return insertData(uri, values);
case DATA_VERSION: return insertVersion(uri, values);
}
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
if(IOUtils.isDatabaseAccessible(getContext())) {
switch(uriMatcher.match(uri)) {
case DATA: return bulkInsertData(uri, values);
case DATA_UPDATE: return bulkInsertData(uri, values);
case DATA_VERSION: return bulkInsertVersion(uri, values);
case CHANNELS: return bulkInsertChannels(uri, values);
}
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
ArrayList<ContentProviderResult> result = new ArrayList<ContentProviderResult>(0);
try {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
try {
database.beginTransaction();
HashMap<Uri, Uri> updateUris = new HashMap<Uri, Uri>();
for(ContentProviderOperation op : operations) {
Uri uri = op.getUri();
String table = TvBrowserDataBaseHelper.DATA_TABLE;
switch(uriMatcher.match(uri)) {
case DATA_VERSION: table = TvBrowserDataBaseHelper.VERSION_TABLE;break;
case DATA_VERSION_ID: table = TvBrowserDataBaseHelper.VERSION_TABLE;break;
case CHANNELS: table = CHANNEL_TABLE;break;
case CHANNEL_ID: table = CHANNEL_TABLE;break;
}
ContentValues values = op.resolveValueBackReferences(null, 0);
String segment = uri.getPathSegments().get(1);
int count = database.update(table, values, KEY_ID + "=" + segment, null);
if(count > 0) {
updateUris.put(uri, uri);
}
result.add(new ContentProviderResult(count));
}
database.setTransactionSuccessful();
database.endTransaction();
Set<Uri> uris = updateUris.keySet();
if(INFORM_FOR_CHANGES) {
for(Uri uri : uris) {
getContext().getContentResolver().notifyChange(uri, null);
switch (uriMatcher.match(uri)) {
case DATA: getContext().getContentResolver().notifyChange(uri, null);break;
case DATA_ID: String segment = uri.getPathSegments().get(1);
getContext().getContentResolver().notifyChange(ContentUris.withAppendedId(CONTENT_URI_DATA_WITH_CHANNEL,Integer.parseInt(segment)),null);
break;
}
}
}
}catch(SQLiteDatabaseLockedException e) {}
}
}catch(RuntimeException rte) {
throw new OperationApplicationException(rte);
}
return result.toArray(new ContentProviderResult[result.size()]);
}
private int bulkInsertData(Uri uri, ContentValues[] values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
int count = 0;
if(database != null) {
database.beginTransaction();
for(ContentValues value : values) {
long rowID = database.insert(TvBrowserDataBaseHelper.DATA_TABLE, "channel", value);
if(rowID != -1) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_DATA, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
count++;
}
}
database.setTransactionSuccessful();
database.endTransaction();
if(count == 0) {
throw new SQLException("Failed to insert row into " + uri + " " + count);
}
}
// Return a count of inserted rows
return count;
}
private int bulkInsertChannels(Uri uri, ContentValues[] values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
int count = 0;
if(database != null) {
database.beginTransaction();
for(ContentValues value : values) {
long rowID = database.insert(CHANNEL_TABLE, "channel", value);
if(rowID != -1) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_CHANNELS, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
count++;
}
}
database.setTransactionSuccessful();
database.endTransaction();
if(count == 0) {
throw new SQLException("Failed to insert row into " + uri + " " + count);
}
}
// Return count of inserted rows
return count;
}
private int bulkInsertVersion(Uri uri, ContentValues[] values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
int count = 0;
if(database != null) {
database.beginTransaction();
for(ContentValues value : values) {
long rowID = database.insert(TvBrowserDataBaseHelper.VERSION_TABLE, "channel", value);
if(rowID != -1) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_DATA_VERSION, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
count++;
}
}
database.setTransactionSuccessful();
database.endTransaction();
if(count == 0) {
throw new SQLException("Failed to insert row into " + uri + " " + count);
}
}
// Return number of inserted rows.
return count;
}
private Uri insertVersion(Uri uri, ContentValues values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
// Insert the new row. The call to databse.insert will return the row number if it is successfull.
long rowID = database.insert(TvBrowserDataBaseHelper.VERSION_TABLE, "version", values);
// Return a URI to the newly inserted row on success.
if(rowID >= 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_DATA_VERSION, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
return newUri;
}
throw new SQLException("Failed to insert row into " + uri + " " + rowID);
}
throw new SQLException("Database not accessible");
}
private Uri insertData(Uri uri, ContentValues values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
// Insert the new row. The call to databse.insert will return the row number if it is successfull.
long rowID = database.insert(TvBrowserDataBaseHelper.DATA_TABLE, "channel", values);
// Return a URI to the newly inserted row on success.
if(rowID >= 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_DATA, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
return newUri;
}
throw new SQLException("Failed to insert row into " + uri + " " + rowID);
}
throw new SQLException("Database not accessible.");
}
private Uri insertChannel(Uri uri, ContentValues values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
// Insert the new row. The call to databse.insert will return the row number if it is successfull.
long rowID = database.insert(CHANNEL_TABLE, "channel", values);
// Return a URI to the newly inserted row on success.
if(rowID >= 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_CHANNELS, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
return newUri;
}
throw new SQLException("Failed to insert row into " + uri + " " + rowID);
}
throw new SQLException("Database not accessible.");
}
private Uri insertGroup(Uri uri, ContentValues values) {
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
// Insert the new row. The call to databse.insert will return the row number if it is successfull.
long rowID = database.insert(TvBrowserDataBaseHelper.GROUPS_TABLE, "group", values);
// Return a URI to the newly inserted row on success.
if(rowID > 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI_GROUPS, rowID);
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(newUri, null);
}
return newUri;
}
throw new SQLException("Failed to insert row into " + uri + " " + rowID);
}
throw new SQLException("Database not accessible.");
}
public void updateDatabasePath() {
mDataBaseHelper.close();
createDataBaseHelper(PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getContext()).getString(getContext().getString(R.string.PREF_DATABASE_PATH), getContext().getString(R.string.pref_database_path_default)));
}
private void createDataBaseHelper(String path) {
if(path.equals(getContext().getString(R.string.pref_database_path_default))) {
path = "";
}
else if(!path.endsWith(File.separator)) {
path += File.separator;
}
Log.d("info11", "DATABASEPATH " + path);
//path = "";
mDataBaseHelper = new TvBrowserDataBaseHelper(getContext(), path + DATABASE_TVB_NAME, null, TvBrowserDataBaseHelper.DATABASE_VERSION);
}
@Override
public boolean onCreate() {
final SharedPreferences pref = PrefUtils.getSharedPreferences(PrefUtils.TYPE_PREFERENCES_SHARED_GLOBAL, getContext());
String databasePath = "internal";
try {
databasePath = pref.getString(getContext().getString(R.string.PREF_DATABASE_PATH), getContext().getString(R.string.pref_database_path_default));
}catch(NotFoundException nfe) {}
createDataBaseHelper(databasePath);
return true;
}
private Cursor rawQueryData(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor result = null;
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
if(projection != null) {
for(int i = 0; i < projection.length; i++) {
if(projection[i].equals(KEY_ID) || projection[i].equals(CHANNEL_KEY_CHANNEL_ID)) {
projection[i] = TvBrowserDataBaseHelper.DATA_TABLE + "." + projection[i]+ " AS " + projection[i];
}
}
}
if(selectionArgs != null) {
for(int i = 0; i < selectionArgs.length; i++) {
if(selectionArgs[i].equals(KEY_ID)) {
selectionArgs[i] = TvBrowserDataBaseHelper.DATA_TABLE + "." + selectionArgs[i];
}
}
}
StringBuilder sql = new StringBuilder();
sql.append("SELECT ");
if(projection == null) {
sql.append("*, ");
}
else {
for(int i = 0; i < projection.length; i++) {
if(i > 0) {
sql.append(", ");
}
sql.append(projection[i]);
}
}
if(selection != null && selection.contains(KEY_ID) && !selection.contains("."+KEY_ID)) {
selection = selection.replace(KEY_ID, TvBrowserDataBaseHelper.DATA_TABLE + "."+KEY_ID);
}
if(selection != null && selection.contains(CHANNEL_KEY_CHANNEL_ID) && !selection.contains("."+CHANNEL_KEY_CHANNEL_ID)) {
selection = selection.replace(CHANNEL_KEY_CHANNEL_ID, TvBrowserDataBaseHelper.DATA_TABLE + "."+CHANNEL_KEY_CHANNEL_ID);
}
String sel = selection.replace(CONCAT_TABLE_PLACE_HOLDER, " FROM " + TvBrowserDataBaseHelper.DATA_TABLE + ", " + CHANNEL_TABLE + " WHERE ");
sql.append(sel);
sql.append(" AND " + CHANNEL_TABLE + "." + KEY_ID + "=" + TvBrowserDataBaseHelper.DATA_TABLE + "." + CHANNEL_KEY_CHANNEL_ID);
String orderBy = CHANNEL_KEY_CHANNEL_ID;
if(sortOrder != null && sortOrder.trim().length() > 0) {
orderBy = sortOrder;
}
if(orderBy != null && !orderBy.contains("NOCASE") && !orderBy.contains("COLLATE")) {
orderBy += " COLLATE NOCASE";
}
if(orderBy != null) {
sql.append(" ORDER BY ").append(orderBy);
}
// Apply the query to the underling database.
result = database.rawQuery(sql.toString(), selectionArgs);
// Register the contexts ContentResolver to be notified if the cursor result set changes.
if(INFORM_FOR_CHANGES) {
result.setNotificationUri(getContext().getContentResolver(), uri);
}
}
return result;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor result = null;
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
try {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
// If no sort order is specified, sort by date / time
String orderBy = null;
// If this is a row query, limit the result set to teh pased in row.
switch(uriMatcher.match(uri)) {
case SEARCH: String search = uri.getPathSegments().get(1).replace("'", "''");
qb.appendWhere("(" + DATA_KEY_TITLE + " LIKE '%" + search + "%' OR " + DATA_KEY_EPISODE_TITLE + " LIKE '%" + search + "%') AND " + DATA_KEY_ENDTIME + ">=" + System.currentTimeMillis() + " AND NOT " + DATA_KEY_DONT_WANT_TO_SEE);
qb.setProjectionMap(SEARCH_PROJECTION_MAP);
qb.setTables(TvBrowserDataBaseHelper.DATA_TABLE);
orderBy = DATA_KEY_STARTTIME;
break;
case GROUP_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case GROUPS: qb.setTables(TvBrowserDataBaseHelper.GROUPS_TABLE);
orderBy = GROUP_KEY_GROUP_ID;break;
case CHANNEL_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case CHANNELS: qb.setTables(CHANNEL_TABLE);
orderBy = CHANNEL_KEY_NAME;break;
case CHANNELGROUPS_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case CHANNELGROUPS:
{
qb.setTables(TvBrowserDataBaseHelper.GROUPS_TABLE + ", " + CHANNEL_TABLE);
orderBy = CHANNEL_KEY_ORDER_NUMBER + ", " + CHANNEL_KEY_NAME;
qb.appendWhere(TvBrowserDataBaseHelper.GROUPS_TABLE + "." + KEY_ID + "=" + CHANNEL_TABLE + "." + GROUP_KEY_GROUP_ID);
if(projection != null) {
for(int i = 0; i < projection.length; i++) {
if(projection[i] != null) {
if((projection[i].equals(KEY_ID) || projection[i].equals(GROUP_KEY_GROUP_ID))) {
projection[i] = TvBrowserDataBaseHelper.GROUPS_TABLE + "." + projection[i]+ " AS " + projection[i];
}
}
}
}
if(selectionArgs != null) {
for(int i = 0; i < selectionArgs.length; i++) {
if(selectionArgs[i].equals(KEY_ID)) {
selectionArgs[i] = TvBrowserDataBaseHelper.GROUPS_TABLE + "." + selectionArgs[i];
}
}
}
if(selection != null) {
if(selection.contains(KEY_ID) && !selection.contains("."+KEY_ID)) {
selection = selection.replace(KEY_ID, TvBrowserDataBaseHelper.GROUPS_TABLE + "."+KEY_ID);
}
if(selection.contains(GROUP_KEY_GROUP_ID) && !selection.contains("."+GROUP_KEY_GROUP_ID)) {
selection = selection.replace(GROUP_KEY_GROUP_ID, TvBrowserDataBaseHelper.GROUPS_TABLE + "."+GROUP_KEY_GROUP_ID);
}
}
}break;
case DATA_VERSION_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case DATA_VERSION: qb.setTables(TvBrowserDataBaseHelper.VERSION_TABLE);
orderBy = VERSION_KEY_DAYS_SINCE_1970;break;
case DATA_UPDATE_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case DATA_UPDATE: qb.setTables(TvBrowserDataBaseHelper.DATA_TABLE);
orderBy = CHANNEL_KEY_CHANNEL_ID;break;
case DATA_ID: qb.appendWhere(KEY_ID + "=" + uri.getPathSegments().get(1));
case DATA: {qb.setTables(TvBrowserDataBaseHelper.DATA_TABLE);
orderBy = CHANNEL_KEY_CHANNEL_ID;
boolean containsStartDayColumn = false;
if(projection != null) {
for(int i = 0; i < projection.length; i++) {
if(projection[i] != null && projection[i].equals(DATA_KEY_START_DAY_LOCAL)) {
containsStartDayColumn = true;
projection[i] = "(strftime('%w', " + DATA_KEY_STARTTIME +
"/1000, 'unixepoch', 'localtime')+1) AS " + DATA_KEY_START_DAY_LOCAL;
}
}
}
if(!containsStartDayColumn && selection != null && selection.contains(DATA_KEY_START_DAY_LOCAL)) {
selection = selection.replace(DATA_KEY_START_DAY_LOCAL, "(strftime('%w', " + DATA_KEY_STARTTIME +
"/1000, 'unixepoch', 'localtime')+1)");
}
} break;
case RAW_DATA_ID: selection += " " + KEY_ID + "=" + uri.getPathSegments().get(1);
case RAW_DATA: return rawQueryData(CONTENT_URI_DATA, projection, selection, selectionArgs, sortOrder);
case DATA_CHANNEL_ID: qb.appendWhere(TvBrowserDataBaseHelper.DATA_TABLE + "." + KEY_ID + "=" + uri.getPathSegments().get(1) + " AND ");
case DATA_CHANNELS: { qb.setTables(TvBrowserDataBaseHelper.DATA_TABLE + " , " + CHANNEL_TABLE);
orderBy = CHANNEL_KEY_ORDER_NUMBER + " , " + CHANNEL_KEY_CHANNEL_ID;
qb.appendWhere(CHANNEL_TABLE + "." + KEY_ID + "=" + TvBrowserDataBaseHelper.DATA_TABLE + "." + CHANNEL_KEY_CHANNEL_ID);
boolean containsStartDayColumn = false;
if(projection != null) {
for(int i = 0; i < projection.length; i++) {
if(projection[i] != null) {
if((projection[i].equals(KEY_ID) || projection[i].equals(CHANNEL_KEY_CHANNEL_ID))) {
projection[i] = TvBrowserDataBaseHelper.DATA_TABLE + "." + projection[i]+ " AS " + projection[i];
}
else if(projection[i].equals(DATA_KEY_START_DAY_LOCAL)) {
projection[i] = "(strftime('%w', " + DATA_KEY_STARTTIME +
"/1000, 'unixepoch', 'localtime')+1) AS " + DATA_KEY_START_DAY_LOCAL;
}
}
}
}
if(selectionArgs != null) {
for(int i = 0; i < selectionArgs.length; i++) {
if(selectionArgs[i].equals(KEY_ID)) {
selectionArgs[i] = TvBrowserDataBaseHelper.DATA_TABLE + "." + selectionArgs[i];
}
}
}
if(selection != null) {
if(selection.contains(KEY_ID) && !selection.contains("."+KEY_ID)) {
selection = selection.replace(KEY_ID, TvBrowserDataBaseHelper.DATA_TABLE + "."+KEY_ID);
}
if(selection.contains(CHANNEL_KEY_CHANNEL_ID) && !selection.contains("."+CHANNEL_KEY_CHANNEL_ID)) {
selection = selection.replace(CHANNEL_KEY_CHANNEL_ID, TvBrowserDataBaseHelper.DATA_TABLE + "."+CHANNEL_KEY_CHANNEL_ID);
}
if(!containsStartDayColumn && selection.contains(DATA_KEY_START_DAY_LOCAL)) {
selection = selection.replace(DATA_KEY_START_DAY_LOCAL, "(strftime('%w', " + DATA_KEY_STARTTIME +
"/1000, 'unixepoch', 'localtime')+1)");
}
}
}break;
default: break;
}
if(sortOrder != null && sortOrder.trim().length() > 0) {
orderBy = sortOrder;
}
if(orderBy != null && !orderBy.contains("NOCASE") && !orderBy.contains("COLLATE") && !orderBy.contains("DESC") && !orderBy.contains("ASC")) {
orderBy += " COLLATE NOCASE";
}
// Apply the query to the underling database.
result = qb.query(database, projection, selection, selectionArgs, null, null, orderBy);
// Register the contexts ContentResolver to be notified if the cursor result set changes.
if(INFORM_FOR_CHANGES) {
result.setNotificationUri(getContext().getContentResolver(), uri);
switch (uriMatcher.match(uri)) {
case DATA: result.setNotificationUri(getContext().getContentResolver(), CONTENT_URI_DATA_WITH_CHANNEL);break;
case DATA_ID: String segment = uri.getPathSegments().get(1);
result.setNotificationUri(getContext().getContentResolver(), ContentUris.withAppendedId(CONTENT_URI_DATA_WITH_CHANNEL,Integer.parseInt(segment)));
break;
}
}
}catch(SQLiteException sqle) {
/* Just ignore the exceptions.
*/
}
}
return result;
}
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
int count = 0;
SQLiteDatabase database = mDataBaseHelper.getWritableDatabase();
if(database != null) {
boolean data_with_channel = false;
switch(uriMatcher.match(uri)) {
case GROUPS: count = database.update(TvBrowserDataBaseHelper.GROUPS_TABLE, values, where, whereArgs);break;
case GROUP_ID: {String segment = uri.getPathSegments().get(1);
count = database.update(TvBrowserDataBaseHelper.GROUPS_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case CHANNELS: count = database.update(CHANNEL_TABLE, values, where, whereArgs);break;
case CHANNEL_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.update(CHANNEL_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA_VERSION: count = database.update(TvBrowserDataBaseHelper.VERSION_TABLE, values, where, whereArgs);break;
case DATA_VERSION_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.update(TvBrowserDataBaseHelper.VERSION_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA_UPDATE: count = database.update(TvBrowserDataBaseHelper.DATA_TABLE, values, where, whereArgs);break;
case DATA_UPDATE_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.update(TvBrowserDataBaseHelper.DATA_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
case DATA: count = database.update(TvBrowserDataBaseHelper.DATA_TABLE, values, where, whereArgs);break;
case DATA_ID: {String segment = uri.getPathSegments().get(1);
data_with_channel = true;
count = database.update(TvBrowserDataBaseHelper.DATA_TABLE, values, KEY_ID + "=" + segment + (!TextUtils.isEmpty(where) ? " AND (" + where + ")" : ""), whereArgs);
}break;
default: throw new IllegalArgumentException("Unknown URI: " + uri);
}
if(INFORM_FOR_CHANGES) {
getContext().getContentResolver().notifyChange(uri, null);
if(data_with_channel) {
getContext().getContentResolver().notifyChange(CONTENT_URI_DATA_WITH_CHANNEL, null);
}
}
}
return count;
}
public static final String CHANNEL_TABLE = "channels";
// Helper class for opneing, creating, and managing database version control
private static class TvBrowserDataBaseHelper extends SQLiteOpenHelper {
private static final String GROUPS_TABLE = "channelGroups";
private static final String DATA_TABLE = "data";
private static final String VERSION_TABLE = "dataVersion";
private static final String CREATE_GROUPS_TABLE = "create table " + GROUPS_TABLE + " (" + KEY_ID + " integer primary key autoincrement, "
+ GROUP_KEY_DATA_SERVICE_ID + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_ID + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_NAME + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_PROVIDER + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_DESCRIPTION + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_MIRRORS + " TEXT NOT NULL, "
+ GROUP_KEY_GROUP_MIRRORS_DEFAULT + " TEXT NOT NULL);";
private static final String CREATE_CHANNEL_TABLE = "create table " + CHANNEL_TABLE + " (" + KEY_ID + " integer primary key autoincrement, "
+ GROUP_KEY_GROUP_ID + " INTEGER REFERENCES " + GROUPS_TABLE + "(" + KEY_ID + ") NOT NULL, "
+ CHANNEL_KEY_CHANNEL_ID + " TEXT NOT NULL, "
+ CHANNEL_KEY_BASE_COUNTRY + " TEXT NOT NULL, "
+ CHANNEL_KEY_TIMEZONE + " TEXT NOT NULL, "
+ CHANNEL_KEY_NAME + " TEXT NOT NULL, "
+ CHANNEL_KEY_COPYRIGHT + " TEXT NOT NULL, "
+ CHANNEL_KEY_WEBSITE + " TEXT NOT NULL, "
+ CHANNEL_KEY_LOGO_URL + " TEXT, "
+ CHANNEL_KEY_LOGO + " BLOB, "
+ CHANNEL_KEY_CATEGORY + " INTEGER NOT NULL, "
+ CHANNEL_KEY_FULL_NAME + " TEXT, "
+ CHANNEL_KEY_ALL_COUNTRIES + " TEXT, "
+ CHANNEL_KEY_JOINED_CHANNEL_ID + " TEXT, "
+ CHANNEL_KEY_ORDER_NUMBER + " INTEGER, "
+ CHANNEL_KEY_SELECTION + " INTEGER NOT NULL DEFAULT 0, "
+ CHANNEL_KEY_USER_CHANNEL_NAME + " TEXT, "
+ CHANNEL_KEY_USER_ICON + " BLOB, "
+ CHANNEL_KEY_USER_START_TIME + " INTEGER, "
+ CHANNEL_KEY_USER_END_TIME + " INTEGER);";
private static final String CREATE_DATA_TABLE = sqlCreateDataTable();
private static final String sqlCreateDataTable() {
final StringBuilder builder = new StringBuilder();
builder.append("create table ").append(DATA_TABLE).append(" (").append(KEY_ID).append(" INTEGER primary key autoincrement, ");
builder.append(CHANNEL_KEY_CHANNEL_ID).append(" INTEGER REFERENCES ").append(CHANNEL_TABLE).append("(").append(KEY_ID).append(") NOT NULL, ");
final String[] keys = MAP_DATA_KEY_TYPE.keySet().toArray(new String[MAP_DATA_KEY_TYPE.size()]);
for(int i = 0; i < keys.length-1; i++) {
builder.append(keys[i]).append(MAP_DATA_KEY_TYPE.get(keys[i])).append(", ");
}
if(keys.length > 0) {
builder.append(keys[keys.length-1]).append(MAP_DATA_KEY_TYPE.get(keys[keys.length-1])).append(" );");
}
return builder.toString();
}
private static final String CREATE_VERSION_TABLE = "create table " + VERSION_TABLE + " (" + KEY_ID + " integer primary key autoincrement, "
+ CHANNEL_KEY_CHANNEL_ID + " INTEGER REFERENCES " + CHANNEL_TABLE + "(" + KEY_ID + ") NOT NULL, "
+ VERSION_KEY_DAYS_SINCE_1970 + " INTEGER NOT NULL, "
+ VERSION_KEY_BASE_VERSION + " INTEGER, "
+ VERSION_KEY_MORE0016_VERSION + " INTEGER, "
+ VERSION_KEY_MORE1600_VERSION + " INTEGER, "
+ VERSION_KEY_PICTURE0016_VERSION + " INTEGER, "
+ VERSION_KEY_PICTURE1600_VERSION + " INTEGER);";
private Context mContext;
public TvBrowserDataBaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context,name, factory, version);
mContext = context.getApplicationContext();
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_GROUPS_TABLE);
db.execSQL(CREATE_CHANNEL_TABLE);
db.execSQL(CREATE_DATA_TABLE);
db.execSQL(CREATE_VERSION_TABLE);
}
private static final int DATABASE_VERSION = 11;
@Override
public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion == 1 && newVersion > 1) {
if(!columnExists(db, CHANNEL_KEY_LOGO)) {
db.execSQL("DROP TABLE IF EXISTS " + DATA_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + CHANNEL_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + GROUPS_TABLE);
db.execSQL("DROP TABLE IF EXISTS " + VERSION_TABLE);
onCreate(db);
}
}
if(oldVersion < 4) {
if(!columnExists(db, DATA_KEY_DONT_WANT_TO_SEE)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_DONT_WANT_TO_SEE + " INTEGER DEFAULT 0");
}
}
if(oldVersion < 5) {
if(!columnExists(db, DATA_KEY_REMOVED_REMINDER)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_REMOVED_REMINDER + " INTEGER DEFAULT 0");
}
}
if(oldVersion < 6) {
final String DATA_KEY_MARKING_VALUES = "markingValues";
if(columnExists(db, DATA_KEY_MARKING_VALUES)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_MARKING_MARKING + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_MARKING_FAVORITE + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_MARKING_FAVORITE_REMINDER + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_MARKING_REMINDER + " INTEGER DEFAULT 0");
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_MARKING_SYNC + " INTEGER DEFAULT 0");
Cursor markings = null;
try {
markings = db.query(DATA_TABLE, new String[] {KEY_ID,DATA_KEY_MARKING_VALUES}, "ifnull("+DATA_KEY_MARKING_VALUES+", '') != ''", null, null, null, KEY_ID);
if(markings.moveToFirst()) {
ArrayList<ContentProviderOperation> updateValuesList = new ArrayList<ContentProviderOperation>();
do {
long id = markings.getLong(0);
String markingValue = markings.getString(1);
ContentValues values = new ContentValues();
final String MARK_VALUE = "marked";
final String MARK_VALUE_FAVORITE = "favorite";
final String MARK_VALUE_SYNC_FAVORITE = "syncfav";
final String MARK_VALUE_REMINDER = "reminder";
if(markingValue.contains(MARK_VALUE)) {
values.put(DATA_KEY_MARKING_MARKING, true);
}
if(markingValue.contains(MARK_VALUE_FAVORITE)) {
values.put(DATA_KEY_MARKING_FAVORITE, true);
}
if(markingValue.contains(MARK_VALUE_REMINDER)) {
if(markingValue.contains(MARK_VALUE_FAVORITE)) {
values.put(DATA_KEY_MARKING_FAVORITE_REMINDER, true);
}
else {
values.put(DATA_KEY_MARKING_REMINDER, true);
}
}
if(markingValue.contains(MARK_VALUE_SYNC_FAVORITE)) {
values.put(DATA_KEY_MARKING_SYNC, true);
}
ContentProviderOperation.Builder opBuilder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_DATA, id));
opBuilder.withValues(values);
updateValuesList.add(opBuilder.build());
}while(markings.moveToNext());
if(!updateValuesList.isEmpty()) {
db.beginTransaction();
for(ContentProviderOperation op : updateValuesList) {
Uri uri = op.getUri();
ContentValues values = op.resolveValueBackReferences(null, 0);
String segment = uri.getPathSegments().get(1);
db.update(TvBrowserDataBaseHelper.DATA_TABLE, values, KEY_ID + "=" + segment, null);
}
db.setTransactionSuccessful();
db.endTransaction();
}
}} finally {IOUtils.close(markings);}
db.execSQL("ALTER TABLE " + DATA_TABLE + " RENAME TO " + DATA_TABLE + "_old");
db.execSQL(CREATE_DATA_TABLE);
StringBuilder columnsSeparated = new StringBuilder();
columnsSeparated.append(KEY_ID).append(",");
columnsSeparated.append(CHANNEL_KEY_CHANNEL_ID).append(",");
columnsSeparated.append(DATA_KEY_STARTTIME).append(",");
columnsSeparated.append(DATA_KEY_ENDTIME).append(",");
columnsSeparated.append(DATA_KEY_TITLE).append(",");
columnsSeparated.append(DATA_KEY_TITLE_ORIGINAL).append(",");
columnsSeparated.append(DATA_KEY_EPISODE_TITLE).append(",");
columnsSeparated.append(DATA_KEY_EPISODE_TITLE_ORIGINAL).append(",");
columnsSeparated.append(DATA_KEY_SHORT_DESCRIPTION).append(",");
columnsSeparated.append(DATA_KEY_DESCRIPTION).append(",");
columnsSeparated.append(DATA_KEY_ACTORS).append(",");
columnsSeparated.append(DATA_KEY_REGIE).append(",");
columnsSeparated.append(DATA_KEY_CUSTOM_INFO).append(",");
columnsSeparated.append(DATA_KEY_CATEGORIES).append(",");
columnsSeparated.append(DATA_KEY_AGE_LIMIT).append(",");
columnsSeparated.append(DATA_KEY_WEBSITE_LINK).append(",");
columnsSeparated.append(DATA_KEY_GENRE).append(",");
columnsSeparated.append(DATA_KEY_ORIGIN).append(",");
columnsSeparated.append(DATA_KEY_NETTO_PLAY_TIME).append(",");
columnsSeparated.append(DATA_KEY_VPS).append(",");
columnsSeparated.append(DATA_KEY_SCRIPT).append(",");
columnsSeparated.append(DATA_KEY_REPETITION_FROM).append(",");
columnsSeparated.append(DATA_KEY_MUSIC).append(",");
columnsSeparated.append(DATA_KEY_MODERATION).append(",");
columnsSeparated.append(DATA_KEY_YEAR).append(",");
columnsSeparated.append(DATA_KEY_REPETITION_ON).append(",");
columnsSeparated.append(DATA_KEY_PICTURE).append(",");
columnsSeparated.append(DATA_KEY_PICTURE_COPYRIGHT).append(",");
columnsSeparated.append(DATA_KEY_PICTURE_DESCRIPTION).append(",");
columnsSeparated.append(DATA_KEY_EPISODE_NUMBER).append(",");
columnsSeparated.append(DATA_KEY_EPISODE_COUNT).append(",");
columnsSeparated.append(DATA_KEY_SEASON_NUMBER).append(",");
columnsSeparated.append(DATA_KEY_PRODUCER).append(",");
columnsSeparated.append(DATA_KEY_CAMERA).append(",");
columnsSeparated.append(DATA_KEY_CUT).append(",");
columnsSeparated.append(DATA_KEY_OTHER_PERSONS).append(",");
columnsSeparated.append(DATA_KEY_RATING).append(",");
columnsSeparated.append(DATA_KEY_PRODUCTION_FIRM).append(",");
columnsSeparated.append(DATA_KEY_AGE_LIMIT_STRING).append(",");
columnsSeparated.append(DATA_KEY_LAST_PRODUCTION_YEAR).append(",");
columnsSeparated.append(DATA_KEY_ADDITIONAL_INFO).append(",");
columnsSeparated.append(DATA_KEY_SERIES).append(",");
columnsSeparated.append(DATA_KEY_UNIX_DATE).append(",");
columnsSeparated.append(DATA_KEY_DATE_PROG_ID).append(",");
columnsSeparated.append(DATA_KEY_DONT_WANT_TO_SEE).append(",");
columnsSeparated.append(DATA_KEY_REMOVED_REMINDER).append(",");
columnsSeparated.append(DATA_KEY_MARKING_MARKING).append(",");
columnsSeparated.append(DATA_KEY_MARKING_FAVORITE).append(",");
columnsSeparated.append(DATA_KEY_MARKING_FAVORITE_REMINDER).append(",");
columnsSeparated.append(DATA_KEY_MARKING_REMINDER).append(",");
columnsSeparated.append(DATA_KEY_MARKING_SYNC);
db.beginTransaction();
db.execSQL("INSERT INTO " + DATA_TABLE + "(" + columnsSeparated + ") SELECT "
+ columnsSeparated + " FROM " + DATA_TABLE + "_old;");
db.setTransactionSuccessful();
db.endTransaction();
db.execSQL("DROP TABLE " + DATA_TABLE + "_old;");
}
}
if(oldVersion < 7) {
ArrayList<String> addColumnList = new ArrayList<String>();
addColumnList.add(DATA_KEY_UTC_START_MINUTE_AFTER_MIDNIGHT);
addColumnList.add(DATA_KEY_UTC_END_MINUTE_AFTER_MIDNIGHT);
addColumnList.add(DATA_KEY_DURATION_IN_MINUTES);
addColumnList.add(DATA_KEY_INFO_BLACK_AND_WHITE);
addColumnList.add(DATA_KEY_INFO_4_TO_3);
addColumnList.add(DATA_KEY_INFO_16_TO_9);
addColumnList.add(DATA_KEY_INFO_MONO);
addColumnList.add(DATA_KEY_INFO_STEREO);
addColumnList.add(DATA_KEY_INFO_DOLBY_SOURROUND);
addColumnList.add(DATA_KEY_INFO_DOLBY_DIGITAL_5_1);
addColumnList.add(DATA_KEY_INFO_SECOND_AUDIO_PROGRAM);
addColumnList.add(DATA_KEY_INFO_CLOSED_CAPTION);
addColumnList.add(DATA_KEY_INFO_LIVE);
addColumnList.add(DATA_KEY_INFO_OMU);
addColumnList.add(DATA_KEY_INFO_FILM);
addColumnList.add(DATA_KEY_INFO_SERIES);
addColumnList.add(DATA_KEY_INFO_NEW);
addColumnList.add(DATA_KEY_INFO_AUDIO_DESCRIPTION);
addColumnList.add(DATA_KEY_INFO_NEWS);
addColumnList.add(DATA_KEY_INFO_SHOW);
addColumnList.add(DATA_KEY_INFO_MAGAZIN);
addColumnList.add(DATA_KEY_INFO_HD);
addColumnList.add(DATA_KEY_INFO_DOCUMENTATION);
addColumnList.add(DATA_KEY_INFO_ART);
addColumnList.add(DATA_KEY_INFO_SPORT);
addColumnList.add(DATA_KEY_INFO_CHILDREN);
addColumnList.add(DATA_KEY_INFO_OTHER);
addColumnList.add(DATA_KEY_INFO_SIGN_LANGUAGE);
addColumnList.add(DATA_KEY_DATE_PROG_STRING_ID);
Cursor c = db.rawQuery("PRAGMA table_info(" + DATA_TABLE + ")", null);
if(c != null) {
try {
c.moveToPosition(-1);
int nameColumn = c.getColumnIndex("name");
while(c.moveToNext()) {
String name = c.getString(nameColumn);
if(addColumnList.contains(name)) {
addColumnList.remove(name);
}
}
}finally {
IOUtils.close(c);
}
}
for(String column : addColumnList) {
if(column.equals(DATA_KEY_DATE_PROG_STRING_ID)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + column + " TEXT");
}
else {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + column + " INTEGER DEFAULT 0");
}
}
new Thread("DATABASE DATA TABLE UPDATE THREAD") {
@Override
public void run() {
Cursor all = db.query(DATA_TABLE, new String[] {KEY_ID,DATA_KEY_STARTTIME,DATA_KEY_ENDTIME,DATA_KEY_CATEGORIES}, null, null, null, null, KEY_ID);
try {
if(all.moveToFirst()) {
final ArrayList<ContentProviderOperation> updateValuesList = new ArrayList<ContentProviderOperation>();
final int keyColumn = all.getColumnIndex(KEY_ID);
final int startTimeColumn = all.getColumnIndex(DATA_KEY_STARTTIME);
final int endTimeColumn = all.getColumnIndex(DATA_KEY_ENDTIME);
final int categoryColumn = all.getColumnIndex(DATA_KEY_CATEGORIES);
Calendar utc = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
do {
long id = all.getLong(keyColumn);
long startTime = all.getLong(startTimeColumn);
long endTime = all.getLong(endTimeColumn);
int categories = all.getInt(categoryColumn);
ContentValues values = new ContentValues();
utc.setTimeInMillis(startTime);
values.put(DATA_KEY_UTC_START_MINUTE_AFTER_MIDNIGHT, (utc.get(Calendar.HOUR_OF_DAY) * 60 + utc.get(Calendar.MINUTE)));
utc.setTimeInMillis(endTime);
values.put(DATA_KEY_UTC_END_MINUTE_AFTER_MIDNIGHT, (utc.get(Calendar.HOUR_OF_DAY) * 60 + utc.get(Calendar.MINUTE)));
values.put(DATA_KEY_DURATION_IN_MINUTES, (int)((endTime - startTime) / 60000));
for(int i = 0; i < IOUtils.INFO_CATEGORIES_ARRAY.length; i++) {
values.put(INFO_CATEGORIES_COLUMNS_ARRAY[i], IOUtils.infoSet(categories, IOUtils.INFO_CATEGORIES_ARRAY[i]));
}
ContentProviderOperation.Builder opBuilder = ContentProviderOperation.newUpdate(ContentUris.withAppendedId(TvBrowserContentProvider.CONTENT_URI_DATA, id));
opBuilder.withValues(values);
updateValuesList.add(opBuilder.build());
}while(all.moveToNext());
if(!updateValuesList.isEmpty()) {
db.beginTransaction();
for(ContentProviderOperation op : updateValuesList) {
Uri uri = op.getUri();
ContentValues values = op.resolveValueBackReferences(null, 0);
String segment = uri.getPathSegments().get(1);
db.update(TvBrowserDataBaseHelper.DATA_TABLE, values, KEY_ID + "=" + segment, null);
}
db.setTransactionSuccessful();
db.endTransaction();
}
}
}finally {
IOUtils.close(all);
}
}
}.start();
}
if(oldVersion >= 7 && oldVersion < 8) {
if(!columnExists(db, DATA_KEY_DATE_PROG_STRING_ID)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_DATE_PROG_STRING_ID + " TEXT");
}
}
if(oldVersion < 9) {
if(!columnExists(db, DATA_KEY_REMOVED_SYNC)) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + DATA_KEY_REMOVED_SYNC + " INTEGER DEFAULT 0");
}
}
if(oldVersion < 10) {
final ArrayList<String> dataKeysList = new ArrayList<String>(MAP_DATA_KEY_TYPE.size());
final Set<String> dataKeySet = MAP_DATA_KEY_TYPE.keySet();
for(String dataKey : dataKeySet) {
dataKeysList.add(dataKey);
}
final Cursor columnNames = db.rawQuery("PRAGMA table_info(" + DATA_TABLE + ")", null);
try {
if(IOUtils.prepareAccess(columnNames)) {
final int columnNameIndex = columnNames.getColumnIndex("name");
if(columnNameIndex >= 0) {
while(columnNames.moveToNext()) {
final String columnName = columnNames.getString(columnNameIndex);
if(columnName != null) {
dataKeysList.remove(columnName.trim());
}
}
}
}
}finally {
IOUtils.close(columnNames);
}
if(!dataKeysList.isEmpty()) {
for(String key : dataKeysList) {
db.execSQL("ALTER TABLE " + DATA_TABLE + " ADD COLUMN " + key + MAP_DATA_KEY_TYPE.get(key));
}
}
}
if(oldVersion < 11) {
db.execSQL("ALTER TABLE " + GROUPS_TABLE + " ADD COLUMN " + GROUP_KEY_GROUP_MIRRORS_DEFAULT);
}
}
@Override
public SQLiteDatabase getWritableDatabase() {
SQLiteDatabase db = null;
if(IOUtils.isDatabaseAccessible(mContext)) {
try {
db = super.getWritableDatabase();
}catch(SQLiteException sqle) {}
}
return db;
}
}
private static final boolean columnExists(SQLiteDatabase db, String columnName) {
return columnExists(db, CHANNEL_TABLE, columnName);
}
private static final boolean columnExists(SQLiteDatabase db, String table, String columnName) {
boolean result = false;
Cursor c = db.rawQuery("PRAGMA table_info(" + table + ")", null);
try {
if(IOUtils.prepareAccess(c)) {
while(c.moveToNext()) {
if(c.getString(c.getColumnIndex("name")).equals(columnName)) {
result = true;
break;
}
}
}
}finally {
IOUtils.close(c);
}
return result;
}
}