Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.tv.dvr.provider;
     18 
     19 import android.content.ContentValues;
     20 import android.content.Context;
     21 import android.database.Cursor;
     22 import android.database.sqlite.SQLiteDatabase;
     23 import android.database.sqlite.SQLiteOpenHelper;
     24 import android.database.sqlite.SQLiteQueryBuilder;
     25 import android.util.Log;
     26 
     27 import com.android.tv.dvr.ScheduledRecording;
     28 import com.android.tv.dvr.provider.DvrContract.Recordings;
     29 
     30 import java.util.ArrayList;
     31 import java.util.List;
     32 
     33 /**
     34  * A data class for one recorded contents.
     35  */
     36 public class DvrDatabaseHelper extends SQLiteOpenHelper {
     37     private static final String TAG = "DvrDatabaseHelper";
     38     private static final boolean DEBUG = true;
     39 
     40     private static final int DATABASE_VERSION = 4;
     41     private static final String DB_NAME = "dvr.db";
     42 
     43     private static final String SQL_CREATE_RECORDINGS =
     44             "CREATE TABLE " + Recordings.TABLE_NAME + "("
     45             + Recordings._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
     46             + Recordings.COLUMN_PRIORITY + " INTEGER DEFAULT " + Long.MAX_VALUE + ","
     47             + Recordings.COLUMN_TYPE + " TEXT NOT NULL,"
     48             + Recordings.COLUMN_CHANNEL_ID + " INTEGER NOT NULL,"
     49             + Recordings.COLUMN_PROGRAM_ID + " INTEGER ,"
     50             + Recordings.COLUMN_START_TIME_UTC_MILLIS + " INTEGER NOT NULL,"
     51             + Recordings.COLUMN_END_TIME_UTC_MILLIS + " INTEGER NOT NULL,"
     52             + Recordings.COLUMN_STATE + " TEXT NOT NULL)";
     53 
     54     private static final String SQL_DROP_RECORDINGS = "DROP TABLE IF EXISTS "
     55             + Recordings.TABLE_NAME;
     56     public static final String WHERE_RECORDING_ID_EQUALS = Recordings._ID + " = ?";
     57 
     58     public DvrDatabaseHelper(Context context) {
     59         super(context.getApplicationContext(), DB_NAME, null, DATABASE_VERSION);
     60     }
     61 
     62     @Override
     63     public void onConfigure(SQLiteDatabase db) {
     64         db.setForeignKeyConstraintsEnabled(true);
     65     }
     66 
     67     @Override
     68     public void onCreate(SQLiteDatabase db) {
     69         if (DEBUG) Log.d(TAG, "Executing SQL: " + SQL_CREATE_RECORDINGS);
     70         db.execSQL(SQL_CREATE_RECORDINGS);
     71     }
     72 
     73     @Override
     74     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
     75         if (DEBUG) Log.d(TAG, "Executing SQL: " + SQL_DROP_RECORDINGS);
     76         db.execSQL(SQL_DROP_RECORDINGS);
     77         onCreate(db);
     78     }
     79 
     80     /**
     81      * Handles the query request and returns a {@link Cursor}.
     82      */
     83     public Cursor query(String tableName, String[] projections) {
     84         SQLiteDatabase db = getReadableDatabase();
     85         SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
     86         builder.setTables(tableName);
     87         return builder.query(db, projections, null, null, null, null, null);
     88     }
     89 
     90     /**
     91      * Inserts recordings.
     92      *
     93      * @return The list of recordings with id set.  The id will be -1 if there was an error.
     94      */
     95     public List<ScheduledRecording> insertRecordings(ScheduledRecording... scheduledRecordings) {
     96         updateChannelsFromRecordings(scheduledRecordings);
     97 
     98         SQLiteDatabase db = getReadableDatabase();
     99         List<ScheduledRecording> results = new ArrayList<>();
    100         for (ScheduledRecording r : scheduledRecordings) {
    101             ContentValues values = ScheduledRecording.toContentValues(r);
    102             long id = db.insert(Recordings.TABLE_NAME, null, values);
    103             results.add(ScheduledRecording.buildFrom(r).setId(id).build());
    104         }
    105         return results;
    106     }
    107 
    108     /**
    109      * Update recordings.
    110      *
    111      * @return The list of row update counts.  The count will be -1 if there was an error or 0
    112      * if no match was found.  The count is expected to be exactly 1 for each recording.
    113      */
    114     public List<Integer> updateRecordings(ScheduledRecording[] scheduledRecordings) {
    115         updateChannelsFromRecordings(scheduledRecordings);
    116         SQLiteDatabase db = getWritableDatabase();
    117         List<Integer> results = new ArrayList<>();
    118         for (ScheduledRecording r : scheduledRecordings) {
    119             ContentValues values = ScheduledRecording.toContentValues(r);
    120             int updated = db.update(Recordings.TABLE_NAME, values, Recordings._ID + " = ?",
    121                     new String[] {String.valueOf(r.getId())});
    122             results.add(updated);
    123         }
    124         return results;
    125     }
    126 
    127     private void updateChannelsFromRecordings(ScheduledRecording[] scheduledRecordings) {
    128        // TODO(DVR) implement/
    129        // TODO(DVR) consider not deleting channels instead of keeping a separate table.
    130     }
    131 
    132     /**
    133      * Delete recordings.
    134      *
    135      * @return The list of row update counts.  The count will be -1 if there was an error or 0
    136      * if no match was found.  The count is expected to be exactly 1 for each recording.
    137      */
    138     public List<Integer> deleteRecordings(ScheduledRecording[] scheduledRecordings) {
    139         SQLiteDatabase db = getWritableDatabase();
    140         List<Integer> results = new ArrayList<>();
    141         for (ScheduledRecording r : scheduledRecordings) {
    142             int deleted = db.delete(Recordings.TABLE_NAME, WHERE_RECORDING_ID_EQUALS,
    143                     new String[] {String.valueOf(r.getId())});
    144             results.add(deleted);
    145         }
    146         return results;
    147     }
    148 }
    149