package com.buddycloud.model.dao;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.buddycloud.model.db.BuddycloudSQLiteOpenHelper;
import com.buddycloud.model.db.PostsTableHelper;
import com.buddycloud.model.db.ThreadsTableHelper;
public class PostsDAO implements DAO<JSONObject, JSONArray> {
private static final int DEF_LIMIT = 30;
private static PostsDAO instance;
private SQLiteDatabase db;
private BuddycloudSQLiteOpenHelper helper;
private PostsDAO(Context context) {
this.helper = BuddycloudSQLiteOpenHelper.getInstance(context);
this.db = helper.getWritableDatabase();
}
public static PostsDAO getInstance(Context context) {
if (instance == null) {
instance = new PostsDAO(context);
}
return instance;
}
private ContentValues buildValues(String id, String author, String published, String updated,
String content, String channel, String replyTo, String media, String threadId) {
ContentValues values = new ContentValues();
values.put(PostsTableHelper.COLUMN_ID, id);
values.put(PostsTableHelper.COLUMN_AUTHOR, author);
values.put(PostsTableHelper.COLUMN_PUBLISHED, published);
values.put(PostsTableHelper.COLUMN_UPDATED, updated);
values.put(PostsTableHelper.COLUMN_CONTENT, content);
values.put(PostsTableHelper.COLUMN_CHANNEL, channel);
values.put(PostsTableHelper.COLUMN_THREAD_ID, threadId);
if (replyTo != null && !replyTo.equals("")) {
values.put(PostsTableHelper.COLUMN_REPLY_TO, replyTo);
}
if (media != null && !media.equals("")) {
values.put(PostsTableHelper.COLUMN_MEDIA, media);
}
return values;
}
private ContentValues buildValues(String channel, JSONObject json) {
String id = json.optString("id");
String author = json.optString("author");
String published = json.optString("published");
String updated = json.optString("updated");
String content = json.isNull("content") ? null : json.optString("content");
String replyTo = json.isNull("replyTo") ? null : json.optString("replyTo");
String threadId = json.optString("threadId");
String mediaId = null;
if (!json.isNull("media")) {
JSONArray mediaArray = json.optJSONArray("media");
if (mediaArray != null) {
mediaId = mediaArray.toString();
} else {
mediaId = json.optString("media");
}
}
return buildValues(id, author, published, updated, content, channel, replyTo,
mediaId, threadId);
}
public boolean insert(String channel, JSONObject json) {
ContentValues values = buildValues(channel, json);
if (values != null) {
long rowId = db.insert(PostsTableHelper.TABLE_NAME, null, values);
return rowId != -1;
}
return false;
}
public boolean update(String channel, JSONObject json) {
ContentValues values = buildValues(channel, json);
if (values != null) {
String filter = PostsTableHelper.COLUMN_CHANNEL + "=\"" + channel + "\"" + " AND " +
PostsTableHelper.COLUMN_ID + "=\"" + values.getAsString(PostsTableHelper.COLUMN_ID) + "\"";
int rowsAffected = db.update(PostsTableHelper.TABLE_NAME,
values, filter, null);
return rowsAffected == 1;
}
return false;
}
public JSONArray get(String channel) {
try {
return get(channel, DEF_LIMIT);
} catch (JSONException e) {
return null;
}
}
public JSONObject get(String channel, String itemId) {
String filter = PostsTableHelper.COLUMN_CHANNEL + "=\"" + channel + "\" AND "
+ PostsTableHelper.COLUMN_ID + "=\"" + itemId + "\"";
return DAOHelper.queryUniqueOnSameThread(db, false, PostsTableHelper.TABLE_NAME, null, filter,
null, null, null, null, null, cursorParser());
}
public int delete(String channel, String itemId) {
String filter = PostsTableHelper.COLUMN_CHANNEL + "=\"" + channel + "\" AND "
+ PostsTableHelper.COLUMN_ID + "=\"" + itemId + "\"";
return DAOHelper.deleteOnSameThread(db, PostsTableHelper.TABLE_NAME, filter, null);
}
public JSONArray getThread(String channel, String threadId) {
String filter = PostsTableHelper.COLUMN_CHANNEL + "=\"" + channel + "\" AND "
+ PostsTableHelper.COLUMN_THREAD_ID + "=\"" + threadId + "\"";
return DAOHelper.queryOnSameThread(db, false, PostsTableHelper.TABLE_NAME, null, filter,
null, null, null, null, null, cursorParser());
}
public JSONArray get(String channel, String after, Integer limit) throws JSONException {
String rawSQL = "SELECT * FROM " + PostsTableHelper.TABLE_NAME + ", " +
"(SELECT " + ThreadsTableHelper.COLUMN_ID + " AS thrId, " +
ThreadsTableHelper.COLUMN_UPDATED + " AS thrUpdated " +
"FROM " + ThreadsTableHelper.TABLE_NAME + " " +
"WHERE " + ThreadsTableHelper.COLUMN_CHANNEL + " = ? " +
(after == null ? "" : "AND " + ThreadsTableHelper.COLUMN_UPDATED + " < ? ") +
"ORDER BY datetime(" + PostsTableHelper.COLUMN_UPDATED + ") DESC LIMIT ?) " +
"WHERE thrId = " + PostsTableHelper.COLUMN_THREAD_ID + " " +
"ORDER BY datetime(thrUpdated) DESC, datetime(" + PostsTableHelper.COLUMN_UPDATED + ") ASC";
List<String> args = new LinkedList<String>();
args.add(channel);
if (after != null) {
args.add(after);
}
args.add(limit.toString());
JSONArray plainResults = DAOHelper.rawQueryOnSameThread(db, cursorParser(),
rawSQL, args.toArray(new String[]{}));
JSONArray threadedResults = new JSONArray();
JSONObject currentThread = null;
for (int i = 0; i < plainResults.length(); i++) {
JSONObject currentItem = plainResults.optJSONObject(i);
if (currentThread == null || !currentThread.optString("threadId").equals(
currentItem.optString("threadId"))) {
threadedResults.put(currentItem);
currentThread = currentItem;
} else {
JSONArray replies = currentThread.optJSONArray("replies");
if (replies == null) {
replies = new JSONArray();
currentThread.put("replies", replies);
}
replies.put(currentItem);
}
}
return threadedResults;
}
public Map<String, JSONArray> getPending() {
String filter = PostsTableHelper.COLUMN_PUBLISHED + " = ''";
return DAOHelper.queryCollectionMapOnSameThread(db, false, PostsTableHelper.TABLE_NAME, null, filter,
null, null, null, null, null, cursorParser(), PostsTableHelper.COLUMN_CHANNEL);
}
public JSONArray get(String channel, int limit) throws JSONException {
return get(channel, null, limit);
}
private DAOCursorParser cursorParser() {
DAOCursorParser cursorParser = new DAOCursorParser() {
@Override
public JSONObject parse(Cursor c) {
return cursorToJSON(c);
}
};
return cursorParser;
}
private JSONObject cursorToJSON(Cursor cursor) {
JSONObject json = new JSONObject();
try {
json.put("id", getString(cursor, PostsTableHelper.COLUMN_ID));
json.put(PostsTableHelper.COLUMN_AUTHOR, getString(cursor, PostsTableHelper.COLUMN_AUTHOR));
json.put(PostsTableHelper.COLUMN_PUBLISHED, getString(cursor, PostsTableHelper.COLUMN_PUBLISHED));
json.put(PostsTableHelper.COLUMN_UPDATED, getString(cursor, PostsTableHelper.COLUMN_UPDATED));
json.put(PostsTableHelper.COLUMN_CHANNEL, getString(cursor, PostsTableHelper.COLUMN_CHANNEL));
json.put(PostsTableHelper.COLUMN_CONTENT, getString(cursor, PostsTableHelper.COLUMN_CONTENT));
json.put(PostsTableHelper.COLUMN_REPLY_TO, getString(cursor, PostsTableHelper.COLUMN_REPLY_TO));
json.put(PostsTableHelper.COLUMN_MEDIA, getString(cursor, PostsTableHelper.COLUMN_MEDIA));
json.put(PostsTableHelper.COLUMN_THREAD_ID, getString(cursor, PostsTableHelper.COLUMN_THREAD_ID));
if (cursor.getColumnIndex("thrUpdated") >= 0) {
json.put("threadUpdated", getString(cursor, "thrUpdated"));
}
} catch (JSONException e) {
return null;
}
return json;
}
private String getString(Cursor cursor, String columnName) {
return cursor.getString(cursor.getColumnIndex(columnName));
}
@Override
public Map<String, JSONArray> getAll() {
return null;
}
}