Database Up and Running

The Database is now fully functional. For the moment the database is not
fully integrated as we do not have all available data yet. Needs to be
filled with proper data.

For the mechanism to upgrade databases please refer to
https://github.com/jgilfelt/android-sqlite-asset-helper/blob/master/samples/database-v1/src/main/java/com/example/MyDatabase.java
This commit is contained in:
Alexander Doerflinger
2017-08-09 14:30:33 +02:00
parent 349c67f093
commit 18293d631c
11 changed files with 94 additions and 161 deletions

7
.idea/dictionaries/aldo7224.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="aldo7224">
<words>
<w>bytestream</w>
</words>
</dictionary>
</component>

View File

@@ -7,8 +7,8 @@ android {
applicationId "com.de.aldo_apps.aldo.mariokartcircuitselector" applicationId "com.de.aldo_apps.aldo.mariokartcircuitselector"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 25 targetSdkVersion 25
versionCode 4 versionCode 5
versionName "0.4" versionName "0.1.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
@@ -26,5 +26,6 @@ dependencies {
}) })
compile 'com.android.support:appcompat-v7:25.+' compile 'com.android.support:appcompat-v7:25.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
} }

View File

@@ -34,6 +34,11 @@ public class Constants {
*/ */
public static final String DATABASE_NAME = "mario_kart_circuit_selector"; public static final String DATABASE_NAME = "mario_kart_circuit_selector";
/**
* Modificator String to modify path of OLD database.
*/
public static final String DATABASE_OLD = "old_";
/** /**
* The name of the table containing all information according accessories. * The name of the table containing all information according accessories.
*/ */

View File

@@ -3,9 +3,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector;
import android.content.ContentValues; import android.content.ContentValues;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Accessory; import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Accessory;
@@ -13,12 +12,16 @@ import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Character;
import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Kart; import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Kart;
import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Track; import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Track;
import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Wheels; import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Wheels;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.DATABASE_NAME;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.DATABASE_OLD;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.DATABASE_PATH;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_AVAILABLE; import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_AVAILABLE;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_GAME; import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_GAME;
import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_ID; import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.KEY_ID;
@@ -34,7 +37,7 @@ import static com.de.aldo_apps.aldo.mariokartcircuitselector.Constants.TABLE_WHE
* @version 0.1 * @version 0.1
* @since 08.08.2017 * @since 08.08.2017
*/ */
public class DatabaseHandler extends SQLiteOpenHelper { public class DatabaseHandler extends SQLiteAssetHelper {
/** /**
* Tag for debugging output. * Tag for debugging output.
@@ -43,135 +46,21 @@ public class DatabaseHandler extends SQLiteOpenHelper {
private final Context mContext; private final Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHandler(final Context context) { public DatabaseHandler(final Context context) {
super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION); super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION);
mContext = context; mContext = context;
} }
@Override
public void onCreate(final SQLiteDatabase sqLiteDatabase) {
mDatabase = sqLiteDatabase; // -------------------------------------------------------------------------------------------
// ---------------- C H A N G E A V A I L A B I L I T Y F U N C T I O N S ----------------
Log.d(TAG, "onCreate: Is new database opened? [" + mDatabase.isOpen() + "]"); // -------------------------------------------------------------------------------------------
if (!checkDataBase()) {
// Maybe the DB already exists but we need to upgrade.
Log.d(TAG, "onCreate: Dropping all Tables (in case they already exist).");
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_GAME);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_ACCESSORY);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_CHARACTER);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_KART);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_RULESET);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + Constants.TABLE_TRACK);
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS " + TABLE_WHEELS);
try {
Log.d(TAG, "onCreate: Copying the Database from Assets Folder to database path.");
copyDataBase();
} catch (IOException exception) {
Log.d(TAG, "onCreate: Could not Copy Database. Exception ["
+ exception.getMessage() + "]");
}
}
}
@Override
public void onUpgrade(final SQLiteDatabase sqLiteDatabase,
final int oldVersion,
final int newVersion) {
// Dropping Tables and Creating them again. All handled by onCreate.
Log.d(TAG, "onUpgrade: Databse was upgraded. Performing upgrade.");
onCreate(sqLiteDatabase);
}
/**
* Check if the database already exist to avoid re-copying the file each time you open the
* application. Also check if the Version Code of the Database changed, so maybe the data need
* to be copied again.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){
Log.d(TAG, "checkDataBase: Checking Database availability.");
SQLiteDatabase checkDB = null;
if (mDatabase != null && mDatabase.isOpen()) {
Log.d(TAG, "checkDataBase: Closing real database to prevent exception when " +
"opening test DB.");
checkDB = mDatabase;
} else {
try {
final String myPath = Constants.DATABASE_PATH + Constants.DATABASE_NAME;
Log.d(TAG, "checkDataBase: Opening Test-Database.");
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (final SQLiteException exception) {
//database does't exist yet.
Log.d(TAG, "checkDataBase: Opening of database throws Exception ["
+ exception.getMessage() + "]. Database seems to not exist yet.");
}
}
// If Database exists we need to close the Database.
if (checkDB != null) {
Log.d(TAG, "checkDataBase: Database seems to exist already.");
// If the Version Code is Lower than the predefined value, we need to upgrade the DB.
if (checkDB.getVersion() < Constants.DATABASE_VERSION) {
Log.d(TAG, "checkDataBase: Database Version code from new and old one differ.");
checkDB.close();
return false;
}
Log.d(TAG, "checkDataBase: Closing Database.");
checkDB.close();
}
return checkDB != null;
}
/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException {
//Open your local db as the input stream
Log.d(TAG, "copyDataBase: Opening InputStream for DB in assets folder.");
final InputStream inputStream = mContext.getAssets().open(Constants.DATABASE_NAME);
// Path to the just created empty db
final String outFileName = Constants.DATABASE_PATH + Constants.DATABASE_NAME;
//Open the empty db as the output stream
Log.d(TAG, "copyDataBase: Opening Outputstream for DB on hard disk [" + outFileName + "]");
final OutputStream outputStream = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
final byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
Log.d(TAG, "copyDataBase: Writing single Chunk of DB from assets to hard disk.");
outputStream.write(buffer, 0, length);
}
//Close the streams
Log.d(TAG, "copyDataBase: Flushing Stream.");
outputStream.flush();
Log.d(TAG, "copyDataBase: Closing Output Stream.");
outputStream.close();
Log.d(TAG, "copyDataBase: Closing Input Stream.");
inputStream.close();
}
/** /**
* Helper method to update the availability status of a single track. * Helper method to update the availability status of a single track.
* *
* @param track The track which should be marked as available/unavailable. * @param track The track which should be marked as available/unavailable.
* @param isAvailable The status of availability to be set. * @param isAvailable The status of availability to be set.
*
* @return The result code of the update function. * @return The result code of the update function.
*/ */
public int changeTrackAvailability(final Track track, final boolean isAvailable) { public int changeTrackAvailability(final Track track, final boolean isAvailable) {
@@ -189,7 +78,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
} }
return db.update(Constants.TABLE_TRACK, values, KEY_ID + " = ?", return db.update(Constants.TABLE_TRACK, values, KEY_ID + " = ?",
new String[] {String.valueOf(track.getId()) }); new String[]{String.valueOf(track.getId())});
} }
/** /**
@@ -197,7 +86,6 @@ public class DatabaseHandler extends SQLiteOpenHelper {
* *
* @param character The character which should be marked as available/unavailable. * @param character The character which should be marked as available/unavailable.
* @param isAvailable The status of availability to be set. * @param isAvailable The status of availability to be set.
*
* @return The result code of the update function. * @return The result code of the update function.
*/ */
public int changeCharacterAvailability(final Character character, final boolean isAvailable) { public int changeCharacterAvailability(final Character character, final boolean isAvailable) {
@@ -214,7 +102,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
} }
return db.update(Constants.TABLE_CHARACTER, values, KEY_ID + " = ?", return db.update(Constants.TABLE_CHARACTER, values, KEY_ID + " = ?",
new String[] {String.valueOf(character.getId()) }); new String[]{String.valueOf(character.getId())});
} }
/** /**
@@ -222,7 +110,6 @@ public class DatabaseHandler extends SQLiteOpenHelper {
* *
* @param kart The kart which should be marked as available/unavailable. * @param kart The kart which should be marked as available/unavailable.
* @param isAvailable The status of availability to be set. * @param isAvailable The status of availability to be set.
*
* @return The result code of the update function. * @return The result code of the update function.
*/ */
public int changeKartAvailability(final Kart kart, final boolean isAvailable) { public int changeKartAvailability(final Kart kart, final boolean isAvailable) {
@@ -243,7 +130,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
} }
return db.update(Constants.TABLE_KART, values, KEY_ID + " = ?", return db.update(Constants.TABLE_KART, values, KEY_ID + " = ?",
new String[] {String.valueOf(kart.getId()) }); new String[]{String.valueOf(kart.getId())});
} }
/** /**
@@ -251,7 +138,6 @@ public class DatabaseHandler extends SQLiteOpenHelper {
* *
* @param accessory The accessory which should be marked as available/unavailable. * @param accessory The accessory which should be marked as available/unavailable.
* @param isAvailable The status of availability to be set. * @param isAvailable The status of availability to be set.
*
* @return The result code of the update function. * @return The result code of the update function.
*/ */
public int changeAccessoryAvailability(final Accessory accessory, final boolean isAvailable) { public int changeAccessoryAvailability(final Accessory accessory, final boolean isAvailable) {
@@ -267,7 +153,7 @@ public class DatabaseHandler extends SQLiteOpenHelper {
} }
return db.update(Constants.TABLE_ACCESSORY, values, KEY_ID + " = ?", return db.update(Constants.TABLE_ACCESSORY, values, KEY_ID + " = ?",
new String[] {String.valueOf(accessory.getId()) }); new String[]{String.valueOf(accessory.getId())});
} }
/** /**
@@ -275,7 +161,6 @@ public class DatabaseHandler extends SQLiteOpenHelper {
* *
* @param wheels The wheels which should be marked as available/unavailable. * @param wheels The wheels which should be marked as available/unavailable.
* @param isAvailable The status of availability to be set. * @param isAvailable The status of availability to be set.
*
* @return The result code of the update function. * @return The result code of the update function.
*/ */
public int changeWheelsAvailability(final Wheels wheels, final boolean isAvailable) { public int changeWheelsAvailability(final Wheels wheels, final boolean isAvailable) {
@@ -291,22 +176,17 @@ public class DatabaseHandler extends SQLiteOpenHelper {
} }
return db.update(TABLE_WHEELS, values, KEY_ID + " = ?", return db.update(TABLE_WHEELS, values, KEY_ID + " = ?",
new String[] {String.valueOf(wheels.getId()) }); new String[]{String.valueOf(wheels.getId())});
} }
public Track testDBConnection(final int id) { public Track testDBConnection(final int id) {
Log.d(TAG, "testDBConnection: Opening Readable Database."); Log.d(TAG, "testDBConnection: Opening Readable Database.");
final SQLiteDatabase dbToUse; final SQLiteDatabase database= this.getReadableDatabase();
if (mDatabase != null && mDatabase.isOpen()) {
dbToUse = mDatabase;
} else {
dbToUse = this.getReadableDatabase();
}
Log.d(TAG, "testDBConnection: Query a single track for id = [" + id + "]"); Log.d(TAG, "testDBConnection: Query a single track for id = [" + id + "]");
Cursor cursor = dbToUse.query(TABLE_TRACK, new String[] { KEY_ID, final Cursor cursor = database.query(TABLE_TRACK, new String[]{KEY_ID,
KEY_NAME, KEY_AVAILABLE }, KEY_ID + "=?", KEY_NAME, KEY_GAME, KEY_AVAILABLE}, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null); new String[]{String.valueOf(id)}, null, null, null, null);
if (cursor != null) { if (cursor != null) {
Log.d(TAG, "testDBConnection: Moving cursor to first."); Log.d(TAG, "testDBConnection: Moving cursor to first.");
cursor.moveToFirst(); cursor.moveToFirst();
@@ -315,15 +195,41 @@ public class DatabaseHandler extends SQLiteOpenHelper {
return null; return null;
} }
Track track = new Track(); DatabaseUtils.dumpCursor(cursor);
final int nameIdx = cursor.getColumnIndex(KEY_NAME);
final int gameIdx = cursor.getColumnIndex(KEY_GAME);
final int idIdx = cursor.getColumnIndex(KEY_ID);
final int availableIdx = cursor.getColumnIndex(KEY_AVAILABLE);
if (nameIdx < 0) {
Log.d(TAG, "testDBConnection: No such column [" + KEY_NAME + "]");
}
if (gameIdx < 0) {
Log.d(TAG, "testDBConnection: No such column [" + KEY_GAME + "]");
}
if (idIdx < 0) {
Log.d(TAG, "testDBConnection: No such column [" + KEY_ID + "]");
}
if (availableIdx < 0) {
Log.d(TAG, "testDBConnection: No such column [" + KEY_AVAILABLE + "]");
}
if (availableIdx >= 0 && idIdx >= 0 && gameIdx >= 0 && nameIdx >= 0) {
final Track track = new Track();
track.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME))); track.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME)));
track.setGame(cursor.getString(cursor.getColumnIndex(KEY_GAME))); track.setGame(cursor.getString(cursor.getColumnIndex(KEY_GAME)));
track.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_ID)))); track.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_ID))));
track.setAvailable(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_AVAILABLE)))); track.setAvailable(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_AVAILABLE))));
database.close();
dbToUse.close();
// return contact // return contact
return track; return track;
}
database.close();
// return contact
return null;
} }
} }

View File

@@ -1,5 +1,6 @@
package com.de.aldo_apps.aldo.mariokartcircuitselector; package com.de.aldo_apps.aldo.mariokartcircuitselector;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.view.View;
@@ -29,9 +30,12 @@ public class GameSelection extends AppCompatActivity {
public void onClick(View view) { public void onClick(View view) {
final int id = Integer.parseInt(editText.getText().toString()); final int id = Integer.parseInt(editText.getText().toString());
final Track track = handler.testDBConnection(id); final Track track = handler.testDBConnection(id);
final String resultStr = track.getGame() + " - " + track.getName() + " - " + track.getAvailable() + " - "; if (track != null) {
final String resultStr = track.getGame() + " - " + track.getName()
+ " - Available = " + track.getAvailable();
result.setText(resultStr); result.setText(resultStr);
} }
}
}); });
} }

View File

@@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants;
/** /**
* The POJO Model for a single accessory object. * The POJO Model for a single accessory object.
* *
@@ -117,8 +119,8 @@ public class Accessory {
* *
* @return the availability state of this accessory object. * @return the availability state of this accessory object.
*/ */
public int getAvailable() { public boolean getAvailable() {
return mAvailable; return mAvailable == Constants.TRUE;
} }
/** /**

View File

@@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants;
/** /**
* The POJO Model for a single character object. * The POJO Model for a single character object.
* *
@@ -144,8 +146,8 @@ public class Character {
* *
* @return the availability state of this character object. * @return the availability state of this character object.
*/ */
public int getAvailable() { public boolean getAvailable() {
return mAvailable; return mAvailable == Constants.TRUE;
} }
/** /**

View File

@@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants;
/** /**
* The POJO Model for a single kart object. * The POJO Model for a single kart object.
* *
@@ -249,8 +251,8 @@ public class Kart {
* *
* @return the availability state of this kart object. * @return the availability state of this kart object.
*/ */
public int getAvailable() { public boolean getAvailable() {
return mAvailable; return mAvailable == Constants.TRUE;
} }
/** /**

View File

@@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants;
/** /**
* The POJO Model for a single track object. * The POJO Model for a single track object.
* *
@@ -168,8 +170,8 @@ public class Track {
* *
* @return the availability state of this track object. * @return the availability state of this track object.
*/ */
public int getAvailable() { public boolean getAvailable() {
return mAvailable; return mAvailable == Constants.TRUE;
} }
/** /**

View File

@@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models;
import android.util.Log; import android.util.Log;
import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants;
/** /**
* The POJO Model for a single wheels object. * The POJO Model for a single wheels object.
* *
@@ -117,8 +119,8 @@ public class Wheels {
* *
* @return the availability state of this wheels object. * @return the availability state of this wheels object.
*/ */
public int getAvailable() { public boolean getAvailable() {
return mAvailable; return mAvailable == Constants.TRUE;
} }
/** /**