package com.jbirdvegas.mgerrit.database;
/*
* Copyright (C) 2013 Android Open Kang Project (AOKP)
* Author: Evan Conway (P4R4N01D), 2013
*
* 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.
*/
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.SparseArray;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
/**
* Base class using reflection to get fields out of the database.
* This class defines a contract that implementing classes must obey. Note that there are
* (constant) static fields that implementing classes MUST provide (see below).
*/
public abstract class DatabaseTable {
// Some helpful error messages for not obeying contracts
protected static final String NO_TABLE_CONST = "Database table must provide static constant 'TABLE'.";
protected static final String PRIVATE_TABLE_CONST = "'TABLE' constant must not be private.";
// Static (constant) fields implementing concrete classes MUST define:
// public static final String TABLE
// public static final int ITEM_LIST
// public static final int ITEM_ID
// public static final Uri CONTENT_URI = Uri.parse(DatabaseFactory.BASE_URI + TABLE);
// public static final String CONTENT_TYPE = DatabaseFactory.BASE_MIME_LIST + TABLE;
// public static final String CONTENT_ITEM_TYPE = DatabaseFactory.BASE_MIME_ITEM + TABLE;
/**
* Executes an SQL script to instanciate its database table
* @param TAG For logging purposes
* @param db An open writable database instance
*/
public abstract void create(String TAG, SQLiteDatabase db);
/* Each subclass MUST implement this static method to facilitate construction
* of its database table. Obviously it cannot be declared abstract as it
* needs to be declared static */
//public static ProjectsTable getInstance();
/* Add an element for the List and ID MIME types for each table.
* These should be used to define the ITEM_LIST and ITEM_ID constants in each table
*/
enum UriType {
ChangesList, ChangesID,
CommitMarkerList, CommitMarkerID,
CommitPropertiesList, CommitPropertiesID,
ConfigList, ConfigID,
FileChangesList, FileChangesID,
FileInfoList, FileInfoID,
MessageInfoList, MessageInfoID,
MoreChangesList, MoreChangesID,
ProjectsList, ProjectsID,
ReviewersList, ReviewersID,
RevisionList, RevisionID,
SelectedChangeList, SelectedChangeID,
SyncTimeList, SyncTimeID,
UserChangesList, UserChangesID,
UserMessageList, UserMessageID,
UserReviewersList, UserReviewersID,
UsersList, UsersID,
}
// Add each DatabaseTable class here, we need to add the virtual tables as well
public static ArrayList<Class<? extends DatabaseTable>> tables;
static {
tables = new ArrayList<>();
tables.add(Changes.class);
tables.add(CommitMarker.class);
tables.add(Config.class);
tables.add(FileChanges.class);
tables.add(FileInfoTable.class);
tables.add(MessageInfo.class);
tables.add(MoreChanges.class);
tables.add(ProjectsTable.class);
tables.add(Reviewers.class);
tables.add(Revisions.class);
tables.add(SelectedChange.class);
tables.add(SyncTime.class);
tables.add(UserChanges.class);
tables.add(UserMessage.class);
tables.add(UserReviewers.class);
tables.add(Users.class);
}
/* Gathers information from the DatabaseTable classes to help implement the
* ContentProvider's getType method, which handles requests for the
* MIME type of the data at the given URI.
*/
public static final SparseArray<String> sContentTypeMap;
static {
sContentTypeMap = new SparseArray<>();
for (Class<? extends DatabaseTable> table : DatabaseTable.tables) {
try {
// Pass nulls in as these are static fields
int key = table.getField("ITEM_LIST").getInt(null);
String value = (String) table.getField("CONTENT_TYPE").get(null);
sContentTypeMap.append(key, value);
key = table.getField("ITEM_ID").getInt(null);
value = (String) table.getField("CONTENT_ITEM_TYPE").get(null);
sContentTypeMap.append(key, value);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Table does not provide sufficient MIME type information", e);
}
}
}
/**
* Gathers the data so it can be determined what URI corresponds to what table.
*/
public static final SparseArray<String> sTableMap;
static {
sTableMap = new SparseArray<>();
for (Class<? extends DatabaseTable> table : DatabaseTable.tables) {
try {
// Pass nulls in as these are static fields
int key = table.getField("ITEM_LIST").getInt(null);
String value = (String) table.getField("TABLE").get(null);
sTableMap.append(key, value);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Unable to initialise table mappings due to inaccessible field", e);
}
}
}
/**
* @param context Context for database access
* @param uri The Uri of the table to search
* @return whether there are any rows in the given table
*/
public static boolean isEmpty(@NotNull Context context, @NotNull Uri uri) {
boolean empty = false;
Cursor cursor = context.getContentResolver().query(uri, new String[] { "count(*)" },
null, null, null);
if (cursor == null) empty = true;
cursor.moveToFirst(); // IMPORTANT
if (!empty) empty = (cursor.getInt(0) <= 0);
cursor.close();
return empty;
}
protected void registerContentObserver(Context context) {
// Do nothing by default
}
protected void unRegisterContentObserver(Context context) {
// Do nothing by default
}
}