diff options
Diffstat (limited to 'mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/database/VersionTable.java')
-rw-r--r-- | mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/database/VersionTable.java | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/database/VersionTable.java b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/database/VersionTable.java new file mode 100644 index 0000000000..d3174e67b2 --- /dev/null +++ b/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/database/VersionTable.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.mozilla.thirdparty.com.google.android.exoplayer2.database; + +import android.content.ContentValues; +import android.database.Cursor; +import android.database.DatabaseUtils; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; +import androidx.annotation.IntDef; +import androidx.annotation.VisibleForTesting; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Utility methods for accessing versions of ExoPlayer database components. This allows them to be + * versioned independently to the version of the containing database. + */ +public final class VersionTable { + + /** Returned by {@link #getVersion(SQLiteDatabase, int, String)} if the version is unset. */ + public static final int VERSION_UNSET = -1; + /** Version of tables used for offline functionality. */ + public static final int FEATURE_OFFLINE = 0; + /** Version of tables used for cache content metadata. */ + public static final int FEATURE_CACHE_CONTENT_METADATA = 1; + /** Version of tables used for cache file metadata. */ + public static final int FEATURE_CACHE_FILE_METADATA = 2; + + private static final String TABLE_NAME = DatabaseProvider.TABLE_PREFIX + "Versions"; + + private static final String COLUMN_FEATURE = "feature"; + private static final String COLUMN_INSTANCE_UID = "instance_uid"; + private static final String COLUMN_VERSION = "version"; + + private static final String WHERE_FEATURE_AND_INSTANCE_UID_EQUALS = + COLUMN_FEATURE + " = ? AND " + COLUMN_INSTANCE_UID + " = ?"; + + private static final String PRIMARY_KEY = + "PRIMARY KEY (" + COLUMN_FEATURE + ", " + COLUMN_INSTANCE_UID + ")"; + private static final String SQL_CREATE_TABLE_IF_NOT_EXISTS = + "CREATE TABLE IF NOT EXISTS " + + TABLE_NAME + + " (" + + COLUMN_FEATURE + + " INTEGER NOT NULL," + + COLUMN_INSTANCE_UID + + " TEXT NOT NULL," + + COLUMN_VERSION + + " INTEGER NOT NULL," + + PRIMARY_KEY + + ")"; + + @Documented + @Retention(RetentionPolicy.SOURCE) + @IntDef({FEATURE_OFFLINE, FEATURE_CACHE_CONTENT_METADATA, FEATURE_CACHE_FILE_METADATA}) + private @interface Feature {} + + private VersionTable() {} + + /** + * Sets the version of a specified instance of a specified feature. + * + * @param writableDatabase The database to update. + * @param feature The feature. + * @param instanceUid The unique identifier of the instance of the feature. + * @param version The version. + * @throws DatabaseIOException If an error occurs executing the SQL. + */ + public static void setVersion( + SQLiteDatabase writableDatabase, @Feature int feature, String instanceUid, int version) + throws DatabaseIOException { + try { + writableDatabase.execSQL(SQL_CREATE_TABLE_IF_NOT_EXISTS); + ContentValues values = new ContentValues(); + values.put(COLUMN_FEATURE, feature); + values.put(COLUMN_INSTANCE_UID, instanceUid); + values.put(COLUMN_VERSION, version); + writableDatabase.replaceOrThrow(TABLE_NAME, /* nullColumnHack= */ null, values); + } catch (SQLException e) { + throw new DatabaseIOException(e); + } + } + + /** + * Removes the version of a specified instance of a feature. + * + * @param writableDatabase The database to update. + * @param feature The feature. + * @param instanceUid The unique identifier of the instance of the feature. + * @throws DatabaseIOException If an error occurs executing the SQL. + */ + public static void removeVersion( + SQLiteDatabase writableDatabase, @Feature int feature, String instanceUid) + throws DatabaseIOException { + try { + if (!tableExists(writableDatabase, TABLE_NAME)) { + return; + } + writableDatabase.delete( + TABLE_NAME, + WHERE_FEATURE_AND_INSTANCE_UID_EQUALS, + featureAndInstanceUidArguments(feature, instanceUid)); + } catch (SQLException e) { + throw new DatabaseIOException(e); + } + } + + /** + * Returns the version of a specified instance of a feature, or {@link #VERSION_UNSET} if no + * version is set. + * + * @param database The database to query. + * @param feature The feature. + * @param instanceUid The unique identifier of the instance of the feature. + * @return The version, or {@link #VERSION_UNSET} if no version is set. + * @throws DatabaseIOException If an error occurs executing the SQL. + */ + public static int getVersion(SQLiteDatabase database, @Feature int feature, String instanceUid) + throws DatabaseIOException { + try { + if (!tableExists(database, TABLE_NAME)) { + return VERSION_UNSET; + } + try (Cursor cursor = + database.query( + TABLE_NAME, + new String[] {COLUMN_VERSION}, + WHERE_FEATURE_AND_INSTANCE_UID_EQUALS, + featureAndInstanceUidArguments(feature, instanceUid), + /* groupBy= */ null, + /* having= */ null, + /* orderBy= */ null)) { + if (cursor.getCount() == 0) { + return VERSION_UNSET; + } + cursor.moveToNext(); + return cursor.getInt(/* COLUMN_VERSION index */ 0); + } + } catch (SQLException e) { + throw new DatabaseIOException(e); + } + } + + @VisibleForTesting + /* package */ static boolean tableExists(SQLiteDatabase readableDatabase, String tableName) { + long count = + DatabaseUtils.queryNumEntries( + readableDatabase, "sqlite_master", "tbl_name = ?", new String[] {tableName}); + return count > 0; + } + + private static String[] featureAndInstanceUidArguments(int feature, String instance) { + return new String[] {Integer.toString(feature), instance}; + } +} |