Started working on implementing a database for storing forum content.
This will enable off line viewing of the forum. Signed-off-by: Ricky Barrette <rickbarrette@gmail.com>
This commit is contained in:
@@ -15,4 +15,5 @@
|
|||||||
<string name="test_password">Test1</string>
|
<string name="test_password">Test1</string>
|
||||||
<string name="osj_server">https://oceanstatejeepsters.ipower.com/forum/mobiquo/mobiquo.php</string>
|
<string name="osj_server">https://oceanstatejeepsters.ipower.com/forum/mobiquo/mobiquo.php</string>
|
||||||
<string name="legal">Legal</string>
|
<string name="legal">Legal</string>
|
||||||
|
<string name="deleteing">Deleteing</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -60,4 +60,9 @@ public class Constraints {
|
|||||||
* Set this boolean to true to enable wtf logging
|
* Set this boolean to true to enable wtf logging
|
||||||
*/
|
*/
|
||||||
public static final boolean WTF = true;
|
public static final boolean WTF = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the database everytime it is initialized
|
||||||
|
*/
|
||||||
|
public static final boolean DROP_TABLES_EVERY_TIME = false;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* DatabaseListener.java
|
||||||
|
* @date Sep 21, 2012
|
||||||
|
* @author ricky barrette
|
||||||
|
*
|
||||||
|
* Copyright 2012 Richard Barrette
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
package org.RickBarrette.osj.forum.database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface will be used to listen to see when the database events are complete
|
||||||
|
*
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public interface DatabaseListener {
|
||||||
|
|
||||||
|
public void onDatabaseCreate();
|
||||||
|
|
||||||
|
public void onDatabaseUpgrade();
|
||||||
|
|
||||||
|
public void onDatabaseUpgradeComplete();
|
||||||
|
|
||||||
|
public void onRestoreComplete();
|
||||||
|
|
||||||
|
public void onDeletionComplete();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,362 @@
|
|||||||
|
/**
|
||||||
|
* ForumDatabase.java
|
||||||
|
* @date Sep 21, 2012
|
||||||
|
* @author ricky barrette
|
||||||
|
*
|
||||||
|
* Copyright 2012 Richard Barrette
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
package org.RickBarrette.osj.forum.database;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.RickBarrette.osj.forum.Constraints;
|
||||||
|
import org.RickBarrette.osj.forum.Log;
|
||||||
|
import org.RickBarrette.osj.forum.R;
|
||||||
|
|
||||||
|
import android.app.ProgressDialog;
|
||||||
|
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.SQLiteOpenHelper;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class will be the main interface between osj forum and it's database
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public class ForumDatabase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper class to manage database creation and version management.
|
||||||
|
*
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
private class OpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new OpenHelper
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public OpenHelper(final Context context) {
|
||||||
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the initial database structure
|
||||||
|
*
|
||||||
|
* @param db
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
private void createDatabase(final SQLiteDatabase db) {
|
||||||
|
db.execSQL("CREATE TABLE " + TABLE + "("+KEY+" TEXT PRIMARY KEY, " + KEY_VALUE + " TEXT)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called when the database is created for the first time. this will create our database
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCreate(final SQLiteDatabase db) {
|
||||||
|
if (Constraints.DROP_TABLES_EVERY_TIME)
|
||||||
|
db.execSQL("DROP TABLE IF EXISTS " + TABLE);
|
||||||
|
createDatabase(db);
|
||||||
|
if(mListener != null)
|
||||||
|
mListener.onDatabaseCreate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called when the database needs to be updated (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase,
|
||||||
|
* int, int)
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
|
||||||
|
Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
|
||||||
|
|
||||||
|
if (mListener != null)
|
||||||
|
mListener.onDatabaseUpgrade();
|
||||||
|
|
||||||
|
isUpgrading = true;
|
||||||
|
|
||||||
|
// upgrade thread
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Looper.prepare();
|
||||||
|
switch (oldVersion) {
|
||||||
|
case 1:
|
||||||
|
//Update stuff here, do not use breaks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String TAG = "ForumDatabase";
|
||||||
|
private final Context mContext;
|
||||||
|
private SQLiteDatabase mDb;
|
||||||
|
private static DatabaseListener mListener;
|
||||||
|
public boolean isUpgrading = false;
|
||||||
|
private final static Handler mHandler;
|
||||||
|
protected static final int DELETIONCOMPLETE = 0;
|
||||||
|
|
||||||
|
protected static final int DATABASEUPGRADECOMPLETE = 1;
|
||||||
|
|
||||||
|
static {
|
||||||
|
mHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(final Message msg) {
|
||||||
|
if (mListener != null)
|
||||||
|
switch (msg.what) {
|
||||||
|
case DELETIONCOMPLETE:
|
||||||
|
mListener.onDeletionComplete();
|
||||||
|
break;
|
||||||
|
case DATABASEUPGRADECOMPLETE:
|
||||||
|
mListener.onDatabaseUpgradeComplete();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Version of this database
|
||||||
|
*/
|
||||||
|
private final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of the database file
|
||||||
|
*/
|
||||||
|
private final String DATABASE_NAME = "osj_forum.db";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Database tables
|
||||||
|
*/
|
||||||
|
private final String TABLE = "table";
|
||||||
|
private final String FORUM_TABLE = "forum_";
|
||||||
|
private final String TOPIC_TABLE = "topic_";
|
||||||
|
private final String THREAD_TABLE = "thread_";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Database keys
|
||||||
|
*/
|
||||||
|
private static final String KEY = "key";
|
||||||
|
private static final String KEY_VALUE = "value";
|
||||||
|
private static final String KEY_FORUM_ID = "forum_id";
|
||||||
|
private static final String KEY_TOPICM_ID = "topic_id";
|
||||||
|
private static final String KEY_THREAD_ID = "thread_id";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a string boolean from the database
|
||||||
|
*
|
||||||
|
* @param bool
|
||||||
|
* @return true or false
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public static boolean parseBoolean(final String bool) {
|
||||||
|
try {
|
||||||
|
return bool == null ? false : Integer.parseInt(bool) == 1 ? true : false;
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ForumDatabase
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public ForumDatabase(final Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new ForumDatabase
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param listener
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public ForumDatabase(final Context context, final DatabaseListener listener) {
|
||||||
|
mListener = listener;
|
||||||
|
mContext = context;
|
||||||
|
mDb = new OpenHelper(mContext).getWritableDatabase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backs up the database
|
||||||
|
*
|
||||||
|
* @return true if successful
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public boolean backup() {
|
||||||
|
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/" + DATABASE_NAME);
|
||||||
|
|
||||||
|
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + mContext.getString(R.string.app_name));
|
||||||
|
if (!exportDir.exists())
|
||||||
|
exportDir.mkdirs();
|
||||||
|
|
||||||
|
final File file = new File(exportDir, dbFile.getName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
file.createNewFile();
|
||||||
|
copyFile(dbFile, file);
|
||||||
|
return true;
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a file
|
||||||
|
*
|
||||||
|
* @param src file
|
||||||
|
* @param dst file
|
||||||
|
* @throws IOException
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
private void copyFile(final File src, final File dst) throws IOException {
|
||||||
|
final FileInputStream in = new FileInputStream(src);
|
||||||
|
final FileOutputStream out = new FileOutputStream(dst);
|
||||||
|
final FileChannel inChannel = in.getChannel();
|
||||||
|
final FileChannel outChannel = out.getChannel();
|
||||||
|
try {
|
||||||
|
inChannel.transferTo(0, inChannel.size(), outChannel);
|
||||||
|
} finally {
|
||||||
|
if (inChannel != null)
|
||||||
|
inChannel.close();
|
||||||
|
if (outChannel != null)
|
||||||
|
outChannel.close();
|
||||||
|
if (in != null)
|
||||||
|
in.close();
|
||||||
|
if (out != null)
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* deletes a note by its row id
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public void deleteTable(final long id) {
|
||||||
|
|
||||||
|
final ProgressDialog progress = ProgressDialog.show(ForumDatabase.this.mContext, "", ForumDatabase.this.mContext.getText(R.string.deleteing), true, true);
|
||||||
|
|
||||||
|
// table deleting thread
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Looper.prepare();
|
||||||
|
|
||||||
|
//Delete stuff here
|
||||||
|
|
||||||
|
mHandler.sendEmptyMessage(DELETIONCOMPLETE);
|
||||||
|
progress.dismiss();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restores the database from the sdcard
|
||||||
|
*
|
||||||
|
* @return true if successful
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public void restore() {
|
||||||
|
final File dbFile = new File(Environment.getDataDirectory() + "/data/" + mContext.getPackageName() + "/databases/" + DATABASE_NAME);
|
||||||
|
|
||||||
|
final File exportDir = new File(Environment.getExternalStorageDirectory(), "/" + mContext.getString(R.string.app_name));
|
||||||
|
if (!exportDir.exists())
|
||||||
|
exportDir.mkdirs();
|
||||||
|
|
||||||
|
final File file = new File(exportDir, dbFile.getName());
|
||||||
|
|
||||||
|
try {
|
||||||
|
file.createNewFile();
|
||||||
|
copyFile(file, dbFile);
|
||||||
|
} catch (final IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* close and reopen the database to upgrade it.
|
||||||
|
*/
|
||||||
|
mDb.close();
|
||||||
|
mDb = new OpenHelper(mContext).getWritableDatabase();
|
||||||
|
if (mDb.isOpen() && !isUpgrading)
|
||||||
|
if (mListener != null)
|
||||||
|
mListener.onRestoreComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* upserts a database table
|
||||||
|
* @param table
|
||||||
|
* @param info
|
||||||
|
* @throws NullPointerException
|
||||||
|
* @author ricky barrette
|
||||||
|
*/
|
||||||
|
public void upsertTable(final String table, final ContentValues info) throws NullPointerException {
|
||||||
|
if (info == null)
|
||||||
|
throw new NullPointerException("info was null");
|
||||||
|
/*
|
||||||
|
* here we wanr to update the information values in the info table
|
||||||
|
*/
|
||||||
|
for (final Entry<String, Object> item : info.valueSet()) {
|
||||||
|
final ContentValues values = new ContentValues();
|
||||||
|
values.put(KEY, item.getKey());
|
||||||
|
try {
|
||||||
|
values.put(KEY_VALUE, (String) item.getValue());
|
||||||
|
} catch (final ClassCastException e) {
|
||||||
|
try {
|
||||||
|
values.put(KEY_VALUE, (Boolean) item.getValue() ? 1 : 0);
|
||||||
|
} catch (final ClassCastException e1) {
|
||||||
|
values.put(KEY_VALUE, (Integer) item.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* here we are going to try to update a row, if that fails we will
|
||||||
|
* insert a row insead
|
||||||
|
*/
|
||||||
|
if (!(mDb.update(table, values, null, null) > 0))
|
||||||
|
mDb.insert(table, null, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user