From 18293d631ca7a6751b812285ccfded6e3fcff84c Mon Sep 17 00:00:00 2001 From: Alexander Doerflinger Date: Wed, 9 Aug 2017 14:30:33 +0200 Subject: [PATCH] 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 --- .idea/dictionaries/aldo7224.xml | 7 + app/build.gradle | 5 +- .../mario_kart_circuit_selector | Bin 39936 -> 39936 bytes .../mariokartcircuitselector/Constants.java | 5 + .../DatabaseHandler.java | 200 +++++------------- .../GameSelection.java | 8 +- .../database_models/Accessory.java | 6 +- .../database_models/Character.java | 6 +- .../database_models/Kart.java | 6 +- .../database_models/Track.java | 6 +- .../database_models/Wheels.java | 6 +- 11 files changed, 94 insertions(+), 161 deletions(-) create mode 100644 .idea/dictionaries/aldo7224.xml rename app/src/main/assets/{ => databases}/mario_kart_circuit_selector (95%) diff --git a/.idea/dictionaries/aldo7224.xml b/.idea/dictionaries/aldo7224.xml new file mode 100644 index 0000000..656c701 --- /dev/null +++ b/.idea/dictionaries/aldo7224.xml @@ -0,0 +1,7 @@ + + + + bytestream + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index e0915b0..4b8b8f7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.de.aldo_apps.aldo.mariokartcircuitselector" minSdkVersion 16 targetSdkVersion 25 - versionCode 4 - versionName "0.4" + versionCode 5 + versionName "0.1.5" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { @@ -26,5 +26,6 @@ dependencies { }) compile 'com.android.support:appcompat-v7:25.+' compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+' testCompile 'junit:junit:4.12' } diff --git a/app/src/main/assets/mario_kart_circuit_selector b/app/src/main/assets/databases/mario_kart_circuit_selector similarity index 95% rename from app/src/main/assets/mario_kart_circuit_selector rename to app/src/main/assets/databases/mario_kart_circuit_selector index a978ba1f8be22afdee81de5263bb79edb639abac..36b858f4323c236cac2ed8e0c57bc535517be67b 100644 GIT binary patch delta 413 zcmZqJ!PKyWX@az%Gy?;JIuI)ZF%u9+P1G@Fl-`&yi3= z?;#@$RKdz1!oV!V^qg@bV-kZ1E3&VG3gKnAqr2-^l93F0QM~*l1gln3R*6n3qzN zpP3S$n_7~Xl30?6&R1~`a&-)GRS0o(@^MvALYG!j(BR@s$jMJm%t=k)3~`MJQSkEz z;!qzSg-}1wz))8mF3x};PhZENNCj`#NDWSiT1_s^$9m26hfs bMqmgiZDwrw!aQjLsycQ?CULO3MH6@cf6Q~M delta 255 zcmZqJ!PKyWX@az%1Oo$uIuI)WF$)lfP1G@Fl-QUsiW)Np!7Gio1q=1m|1cM~Q=83vtj6ki7RTCT4nHU2%Hu^HMX{xh{+lo(4D3aLB zs?X>sGM$0>B2zO{6ytOzO$KG4JwPy7s=$dSJ}u^_e>(8*7jCuy*3W@%vN W*euZUof%9_4B(!m0~DO_hZ_KKVmtHz diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/Constants.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/Constants.java index f26048c..919bd0e 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/Constants.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/Constants.java @@ -34,6 +34,11 @@ public class Constants { */ 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. */ diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/DatabaseHandler.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/DatabaseHandler.java index 0c5d2ad..aa95993 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/DatabaseHandler.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/DatabaseHandler.java @@ -3,9 +3,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; +import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; 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.Track; import com.de.aldo_apps.aldo.mariokartcircuitselector.database_models.Wheels; +import com.readystatesoftware.sqliteasset.SQLiteAssetHelper; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; 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_GAME; 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 * @since 08.08.2017 */ -public class DatabaseHandler extends SQLiteOpenHelper { +public class DatabaseHandler extends SQLiteAssetHelper { /** * Tag for debugging output. @@ -43,135 +46,21 @@ public class DatabaseHandler extends SQLiteOpenHelper { private final Context mContext; - private SQLiteDatabase mDatabase; - public DatabaseHandler(final Context context) { super(context, Constants.DATABASE_NAME, null, Constants.DATABASE_VERSION); mContext = context; } - @Override - public void onCreate(final SQLiteDatabase sqLiteDatabase) { - mDatabase = sqLiteDatabase; - - 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(); - - } + // ------------------------------------------------------------------------------------------- + // ---------------- 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 ---------------- + // ------------------------------------------------------------------------------------------- /** * Helper method to update the availability status of a single track. * * @param track The track which should be marked as available/unavailable. * @param isAvailable The status of availability to be set. - * * @return The result code of the update function. */ 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 + " = ?", - 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 isAvailable The status of availability to be set. - * * @return The result code of the update function. */ public int changeCharacterAvailability(final Character character, final boolean isAvailable) { @@ -214,15 +102,14 @@ public class DatabaseHandler extends SQLiteOpenHelper { } return db.update(Constants.TABLE_CHARACTER, values, KEY_ID + " = ?", - new String[] {String.valueOf(character.getId()) }); + new String[]{String.valueOf(character.getId())}); } /** * Helper method to update the availability status of a single kart. * - * @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. - * * @return The result code of the update function. */ 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 + " = ?", - 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 isAvailable The status of availability to be set. - * * @return The result code of the update function. */ public int changeAccessoryAvailability(final Accessory accessory, final boolean isAvailable) { @@ -267,15 +153,14 @@ public class DatabaseHandler extends SQLiteOpenHelper { } return db.update(Constants.TABLE_ACCESSORY, values, KEY_ID + " = ?", - new String[] {String.valueOf(accessory.getId()) }); + new String[]{String.valueOf(accessory.getId())}); } /** * Helper method to update the availability status of a single wheels. * - * @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. - * * @return The result code of the update function. */ 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 + " = ?", - new String[] {String.valueOf(wheels.getId()) }); + new String[]{String.valueOf(wheels.getId())}); } public Track testDBConnection(final int id) { Log.d(TAG, "testDBConnection: Opening Readable Database."); - final SQLiteDatabase dbToUse; - if (mDatabase != null && mDatabase.isOpen()) { - dbToUse = mDatabase; - } else { - dbToUse = this.getReadableDatabase(); - } + final SQLiteDatabase database= this.getReadableDatabase(); Log.d(TAG, "testDBConnection: Query a single track for id = [" + id + "]"); - Cursor cursor = dbToUse.query(TABLE_TRACK, new String[] { KEY_ID, - KEY_NAME, KEY_AVAILABLE }, KEY_ID + "=?", - new String[] { String.valueOf(id) }, null, null, null, null); + final Cursor cursor = database.query(TABLE_TRACK, new String[]{KEY_ID, + KEY_NAME, KEY_GAME, KEY_AVAILABLE}, KEY_ID + "=?", + new String[]{String.valueOf(id)}, null, null, null, null); if (cursor != null) { Log.d(TAG, "testDBConnection: Moving cursor to first."); cursor.moveToFirst(); @@ -315,15 +195,41 @@ public class DatabaseHandler extends SQLiteOpenHelper { return null; } - Track track = new Track(); - track.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME))); - track.setGame(cursor.getString(cursor.getColumnIndex(KEY_GAME))); - track.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_ID)))); - track.setAvailable(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_AVAILABLE)))); + DatabaseUtils.dumpCursor(cursor); - dbToUse.close(); + 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.setGame(cursor.getString(cursor.getColumnIndex(KEY_GAME))); + track.setId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_ID)))); + track.setAvailable(Integer.parseInt(cursor.getString(cursor.getColumnIndex(KEY_AVAILABLE)))); + database.close(); + + // return contact + return track; + + } + database.close(); // return contact - return track; + return null; } } diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/GameSelection.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/GameSelection.java index d38be24..e2db914 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/GameSelection.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/GameSelection.java @@ -1,5 +1,6 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector; +import android.database.sqlite.SQLiteDatabase; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; @@ -29,8 +30,11 @@ public class GameSelection extends AppCompatActivity { public void onClick(View view) { final int id = Integer.parseInt(editText.getText().toString()); final Track track = handler.testDBConnection(id); - final String resultStr = track.getGame() + " - " + track.getName() + " - " + track.getAvailable() + " - "; - result.setText(resultStr); + if (track != null) { + final String resultStr = track.getGame() + " - " + track.getName() + + " - Available = " + track.getAvailable(); + result.setText(resultStr); + } } }); diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Accessory.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Accessory.java index bff9368..3ef76b2 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Accessory.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Accessory.java @@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models; import android.util.Log; +import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants; + /** * The POJO Model for a single accessory object. * @@ -117,8 +119,8 @@ public class Accessory { * * @return the availability state of this accessory object. */ - public int getAvailable() { - return mAvailable; + public boolean getAvailable() { + return mAvailable == Constants.TRUE; } /** diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Character.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Character.java index bde48cd..0d52b8c 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Character.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Character.java @@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models; import android.util.Log; +import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants; + /** * The POJO Model for a single character object. * @@ -144,8 +146,8 @@ public class Character { * * @return the availability state of this character object. */ - public int getAvailable() { - return mAvailable; + public boolean getAvailable() { + return mAvailable == Constants.TRUE; } /** diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Kart.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Kart.java index e95f9a2..565895e 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Kart.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Kart.java @@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models; import android.util.Log; +import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants; + /** * The POJO Model for a single kart object. * @@ -249,8 +251,8 @@ public class Kart { * * @return the availability state of this kart object. */ - public int getAvailable() { - return mAvailable; + public boolean getAvailable() { + return mAvailable == Constants.TRUE; } /** diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Track.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Track.java index 3148dd1..8808c3e 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Track.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Track.java @@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models; import android.util.Log; +import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants; + /** * The POJO Model for a single track object. * @@ -168,8 +170,8 @@ public class Track { * * @return the availability state of this track object. */ - public int getAvailable() { - return mAvailable; + public boolean getAvailable() { + return mAvailable == Constants.TRUE; } /** diff --git a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Wheels.java b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Wheels.java index 3da68ec..ae55d2e 100644 --- a/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Wheels.java +++ b/app/src/main/java/com/de/aldo_apps/aldo/mariokartcircuitselector/database_models/Wheels.java @@ -2,6 +2,8 @@ package com.de.aldo_apps.aldo.mariokartcircuitselector.database_models; import android.util.Log; +import com.de.aldo_apps.aldo.mariokartcircuitselector.Constants; + /** * The POJO Model for a single wheels object. * @@ -117,8 +119,8 @@ public class Wheels { * * @return the availability state of this wheels object. */ - public int getAvailable() { - return mAvailable; + public boolean getAvailable() { + return mAvailable == Constants.TRUE; } /**