package com.shvelo.guesslogo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.ArrayList; import java.util.List; import com.google.gson.Gson; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.util.Log; public class DBHelper extends SQLiteOpenHelper { private SQLiteDatabase database; private final Context context; private static final String DATABASE_NAME = "brands.db3"; private static final int DATABASE_VERSION = 5; /** * Constructor Takes and keeps a reference of the passed context in order to * access to the application assets and resources. * * @param context */ public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; database = getWritableDatabase(); if(checkJSON()) { update(database, null, null); } } /** * Close the database */ @Override public synchronized void close() { if (database != null) database.close(); super.close(); } /** * Get the database * @return SQLiteDatabase */ public SQLiteDatabase get() { return database; } @Override public void onCreate(SQLiteDatabase db) { database = db; execSQLFile("schema.sql", db); loadDB(db); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { update(db, oldVersion, newVersion); } public boolean checkJSON() { try { DigestInputStream is; InputStream inputStream; MessageDigest md = MessageDigest.getInstance("MD5"); inputStream = context.getAssets().open("brands.json"); is = new DigestInputStream(inputStream, md); String digest = new String(md.digest(),"UTF-8"); is.close(); Cursor cursor = database.rawQuery("SELECT value FROM userdata WHERE name='json_checksum'", null); cursor.moveToFirst(); String storedDigest = cursor.getString(0); Log.d("guesslogo","Digest: "+digest); Log.d("guesslogo","Stored digest: "+storedDigest); if(digest == storedDigest) { return false; } else { Log.d("guesslogo", "Updating stored digest "+digest); database.rawQuery("UPDATE userdata SET value='"+digest+"' WHERE name='json_checksum'", null); return true; } } catch (Exception e) { e.printStackTrace(); } return false; } public void update(SQLiteDatabase db, Integer oldVersion, Integer newVersion) { if(oldVersion == null) oldVersion = DATABASE_VERSION; if(newVersion == null) newVersion = DATABASE_VERSION; List<Integer> guessed = new ArrayList<Integer>(); Cursor query = db.query("brands", null, null, null, null, null, "name asc", null); for(int i = 0; i < query.getCount(); i++) { query.moveToNext(); if(query.getInt(query.getColumnIndex("guessed")) == 1) guessed.add(query.getInt(query.getColumnIndex("_id"))); } int score = 0; String checksum = ""; if(oldVersion >= 4) { Cursor cursor = db.rawQuery("SELECT value FROM userdata WHERE name='score'", null); cursor.moveToFirst(); score = cursor.getInt(0); } if(oldVersion >= 5) { Cursor cursor = db.rawQuery("SELECT value FROM userdata WHERE name='json_checksum'", null); cursor.moveToFirst(); checksum = cursor.getString(0); } execSQLFile("schema_drop.sql", db); execSQLFile("schema.sql", db); loadDB(db); db.beginTransaction(); for(int i = 0; i < guessed.size(); i++) { db.execSQL("UPDATE brands SET guessed=1 WHERE _id=?", new String[] { guessed.get(i).toString() }); } if(oldVersion >= 4 && score > 0) { db.rawQuery("UPDATE userdata SET value=? WHERE name='score'", new String[]{ String.valueOf(score) }); } db.rawQuery("UPDATE userdata SET value=? WHERE name='json_checksum'", new String[]{ checksum }); db.setTransactionSuccessful(); db.endTransaction(); } private void loadDB(SQLiteDatabase db) { try { loadLogos(db); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } } private void loadLogos(SQLiteDatabase db) throws IOException { InputStream inputStream = context.getAssets().open("brands.json"); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; StringBuilder jsonBuilder = new StringBuilder(); while ((line = reader.readLine()) != null) { jsonBuilder.append(line); } Gson gson = new Gson(); BrandEntry[] brands = gson.fromJson(jsonBuilder.toString(), BrandEntry[].class); db.beginTransaction(); try { for(int i = 0; i < brands.length; i++) { BrandEntry brandEntry = brands[i]; db.execSQL( "INSERT INTO brands(name,logo,variant1,variant2,variant3,variant4,correct,guessed) values(?,?,?,?,?,?,?,0);" , new String[]{ brandEntry.name, //name "@drawable/" + brandEntry.logo, //logo brandEntry.variants[0], brandEntry.variants[1], brandEntry.variants[2] ,brandEntry.variants[3], //variants String.valueOf(brandEntry.correct) //correct answer }); } db.setTransactionSuccessful(); } finally { reader.close(); db.endTransaction(); } } private String readFile(String name) throws IOException { InputStream inputStream = context.getAssets().open(name); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; StringBuilder builder = new StringBuilder(); while ((line = reader.readLine()) != null) { builder.append(line); } return builder.toString(); } private void execSQLFile(String name, SQLiteDatabase db) { try { String sql = readFile(name); String[] lines = sql.split("(?!\".*?;.*?\")(?!'.*?;.*?');"); for(int i = 0; i < lines.length; i++) { Log.d("guesslogo", lines[i]); String statement = lines[i]; statement.replaceAll("[\\s\\n\\t ]",""); if(statement.length() > 0) db.execSQL(statement); } } catch (Exception e) { e.printStackTrace(); } } }