blob: dc61bbb3a9a1df139ba7851f903f8e5a06853908 [file] [log] [blame]
package org.wordpress.android.datasets;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import org.wordpress.android.models.ReaderComment;
import org.wordpress.android.models.ReaderCommentList;
import org.wordpress.android.models.ReaderPost;
import org.wordpress.android.util.SqlUtils;
/**
* stores comments on reader posts
*/
public class ReaderCommentTable {
private static final String COLUMN_NAMES =
" blog_id,"
+ " post_id,"
+ " comment_id,"
+ " parent_id,"
+ " author_name,"
+ " author_avatar,"
+ " author_url,"
+ " author_id,"
+ " author_blog_id,"
+ " published,"
+ " timestamp,"
+ " status,"
+ " text,"
+ " num_likes,"
+ " is_liked,"
+ " page_number";
protected static void createTables(SQLiteDatabase db) {
db.execSQL("CREATE TABLE tbl_comments ("
+ " blog_id INTEGER DEFAULT 0,"
+ " post_id INTEGER DEFAULT 0,"
+ " comment_id INTEGER DEFAULT 0,"
+ " parent_id INTEGER DEFAULT 0,"
+ " author_name TEXT,"
+ " author_avatar TEXT,"
+ " author_url TEXT,"
+ " author_id INTEGER DEFAULT 0,"
+ " author_blog_id INTEGER DEFAULT 0,"
+ " published TEXT,"
+ " timestamp INTEGER DEFAULT 0,"
+ " status TEXT,"
+ " text TEXT,"
+ " num_likes INTEGER DEFAULT 0,"
+ " is_liked INTEGER DEFAULT 0,"
+ " page_number INTEGER DEFAULT 0,"
+ " PRIMARY KEY (blog_id, post_id, comment_id))");
db.execSQL("CREATE INDEX idx_page_number ON tbl_comments(page_number)");
}
protected static void dropTables(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS tbl_comments");
}
protected static void reset(SQLiteDatabase db) {
dropTables(db);
createTables(db);
}
protected static int purge(SQLiteDatabase db) {
// purge comments attached to posts that no longer exist
int numDeleted = db.delete("tbl_comments", "post_id NOT IN (SELECT DISTINCT post_id FROM tbl_posts)", null);
// purge all but the first page of comments
numDeleted += db.delete("tbl_comments", "page_number != 1", null);
return numDeleted;
}
public static boolean isEmpty() {
return (getNumComments()==0);
}
private static int getNumComments() {
long count = SqlUtils.getRowCount(ReaderDatabase.getReadableDb(), "tbl_comments");
return (int)count;
}
/*
* returns the highest page_number for comments on the passed post
*/
public static int getLastPageNumberForPost(long blogId, long postId) {
String[] args = {Long.toString(blogId), Long.toString(postId)};
return SqlUtils.intForQuery(ReaderDatabase.getReadableDb(),
"SELECT MAX(page_number) FROM tbl_comments WHERE blog_id=? AND post_id=?", args);
}
/*
* returns the page number for a specific comment
*/
public static int getPageNumberForComment(long blogId, long postId, long commentId) {
String[] args = {Long.toString(blogId), Long.toString(postId), Long.toString(commentId)};
return SqlUtils.intForQuery(ReaderDatabase.getReadableDb(),
"SELECT page_number FROM tbl_comments WHERE blog_id=? AND post_id=? AND comment_id=?", args);
}
/*
* removes all comments for the passed post
*/
public static void purgeCommentsForPost(long blogId, long postId) {
String[] args = {Long.toString(blogId), Long.toString(postId)};
ReaderDatabase.getWritableDb().delete("tbl_comments", "blog_id=? AND post_id=?", args);
}
/*
* returns the #comments stored locally for this post, which may differ from ReaderPostTable.getNumCommentsOnPost
* (which is the #comments the server says exist for this post)
*/
public static int getNumCommentsForPost(ReaderPost post) {
if (post == null) {
return 0;
}
return getNumCommentsForPost(post.blogId, post.postId);
}
private static int getNumCommentsForPost(long blogId, long postId) {
String[] args = {Long.toString(blogId), Long.toString(postId)};
return SqlUtils.intForQuery(ReaderDatabase.getReadableDb(), "SELECT count(*) FROM tbl_comments WHERE blog_id=? AND post_id=?", args);
}
public static ReaderCommentList getCommentsForPost(ReaderPost post) {
if (post == null) {
return new ReaderCommentList();
}
String[] args = {Long.toString(post.blogId), Long.toString(post.postId)};
Cursor c = ReaderDatabase.getReadableDb().rawQuery("SELECT * FROM tbl_comments WHERE blog_id=? AND post_id=? ORDER BY timestamp", args);
try {
ReaderCommentList comments = new ReaderCommentList();
if (c.moveToFirst()) {
do {
comments.add(getCommentFromCursor(c));
} while (c.moveToNext());
}
return comments;
} finally {
SqlUtils.closeCursor(c);
}
}
public static void addOrUpdateComment(ReaderComment comment) {
if (comment == null) {
return;
}
ReaderCommentList comments = new ReaderCommentList();
comments.add(comment);
addOrUpdateComments(comments);
}
public static void addOrUpdateComments(ReaderCommentList comments) {
if (comments == null || comments.size() == 0) {
return;
}
SQLiteDatabase db = ReaderDatabase.getWritableDb();
db.beginTransaction();
SQLiteStatement stmt = db.compileStatement("INSERT OR REPLACE INTO tbl_comments ("
+ COLUMN_NAMES
+ ") VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9,?10,?11,?12,?13,?14,?15,?16)");
try {
for (ReaderComment comment: comments) {
stmt.bindLong (1, comment.blogId);
stmt.bindLong (2, comment.postId);
stmt.bindLong (3, comment.commentId);
stmt.bindLong (4, comment.parentId);
stmt.bindString(5, comment.getAuthorName());
stmt.bindString(6, comment.getAuthorAvatar());
stmt.bindString(7, comment.getAuthorUrl());
stmt.bindLong (8, comment.authorId);
stmt.bindLong (9, comment.authorBlogId);
stmt.bindString(10, comment.getPublished());
stmt.bindLong (11, comment.timestamp);
stmt.bindString(12, comment.getStatus());
stmt.bindString(13, comment.getText());
stmt.bindLong (14, comment.numLikes);
stmt.bindLong (15, SqlUtils.boolToSql(comment.isLikedByCurrentUser));
stmt.bindLong (16, comment.pageNumber);
stmt.execute();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
SqlUtils.closeStatement(stmt);
}
}
public static ReaderComment getComment(long blogId, long postId, long commentId) {
String[] args = new String[] {Long.toString(blogId), Long.toString(postId), Long.toString(commentId)};
Cursor c = ReaderDatabase.getReadableDb().rawQuery(
"SELECT * FROM tbl_comments WHERE blog_id=? AND post_id=? AND comment_id=? LIMIT 1", args);
try {
if (!c.moveToFirst()) {
return null;
}
return getCommentFromCursor(c);
} finally {
SqlUtils.closeCursor(c);
}
}
public static void deleteComment(ReaderPost post, long commentId) {
if (post == null) {
return;
}
String[] args = {Long.toString(post.blogId), Long.toString(post.postId), Long.toString(commentId)};
ReaderDatabase.getWritableDb().delete("tbl_comments", "blog_id=? AND post_id=? AND comment_id=?", args);
}
/*
* returns true if any of the passed comments don't already exist
* IMPORTANT: assumes passed comments are all for the same post
*/
public static boolean hasNewComments(ReaderCommentList comments) {
if (comments == null || comments.size() == 0) {
return false;
}
StringBuilder sb = new StringBuilder(
"SELECT COUNT(*) FROM tbl_comments WHERE blog_id=? AND post_id=? AND comment_id IN (");
boolean isFirst = true;
for (ReaderComment comment: comments) {
if (isFirst) {
isFirst = false;
} else {
sb.append(",");
}
sb.append(comment.commentId);
}
sb.append(")");
String[] args = {Long.toString(comments.get(0).blogId),
Long.toString(comments.get(0).postId)};
int numExisting = SqlUtils.intForQuery(ReaderDatabase.getReadableDb(), sb.toString(), args);
return numExisting != comments.size();
}
/*
* returns the #likes known to exist for this comment
*/
public static int getNumLikesForComment(long blogId, long postId, long commentId) {
String[] args = {Long.toString(blogId),
Long.toString(postId),
Long.toString(commentId)};
return SqlUtils.intForQuery(ReaderDatabase.getReadableDb(),
"SELECT num_likes FROM tbl_comments WHERE blog_id=? AND post_id=? AND comment_id=?",
args);
}
/*
* updates both the like count for a comment and whether it's liked by the current user
*/
public static void setLikesForComment(ReaderComment comment, int numLikes, boolean isLikedByCurrentUser) {
if (comment == null) {
return;
}
String[] args =
{Long.toString(comment.blogId),
Long.toString(comment.postId),
Long.toString(comment.commentId)};
ContentValues values = new ContentValues();
values.put("num_likes", numLikes);
values.put("is_liked", SqlUtils.boolToSql(isLikedByCurrentUser));
ReaderDatabase.getWritableDb().update(
"tbl_comments",
values,
"blog_id=? AND post_id=? AND comment_id=?",
args);
}
public static boolean isCommentLikedByCurrentUser(ReaderComment comment) {
if (comment == null) {
return false;
}
return isCommentLikedByCurrentUser(comment.blogId, comment.postId, comment.commentId);
}
public static boolean isCommentLikedByCurrentUser(long blogId, long postId, long commentId) {
String[] args = {Long.toString(blogId),
Long.toString(postId),
Long.toString(commentId)};
return SqlUtils.boolForQuery(ReaderDatabase.getReadableDb(),
"SELECT is_liked FROM tbl_comments WHERE blog_id=? AND post_id=? and comment_id=?",
args);
}
public static boolean commentExists(long blogId, long postId, long commentId) {
String[] args = {Long.toString(blogId),
Long.toString(postId),
Long.toString(commentId)};
return SqlUtils.boolForQuery(ReaderDatabase.getReadableDb(),
"SELECT 1 FROM tbl_comments WHERE blog_id=? AND post_id=? AND comment_id=?", args);
}
private static ReaderComment getCommentFromCursor(Cursor c) {
if (c == null) {
throw new IllegalArgumentException("null comment cursor");
}
ReaderComment comment = new ReaderComment();
comment.commentId = c.getLong(c.getColumnIndex("comment_id"));
comment.blogId = c.getLong(c.getColumnIndex("blog_id"));
comment.postId = c.getLong(c.getColumnIndex("post_id"));
comment.parentId = c.getLong(c.getColumnIndex("parent_id"));
comment.setPublished(c.getString(c.getColumnIndex("published")));
comment.timestamp = c.getLong(c.getColumnIndex("timestamp"));
comment.setAuthorAvatar(c.getString(c.getColumnIndex("author_avatar")));
comment.setAuthorName(c.getString(c.getColumnIndex("author_name")));
comment.setAuthorUrl(c.getString(c.getColumnIndex("author_url")));
comment.authorId = c.getLong(c.getColumnIndex("author_id"));
comment.authorBlogId = c.getLong(c.getColumnIndex("author_blog_id"));
comment.setStatus(c.getString(c.getColumnIndex("status")));
comment.setText(c.getString(c.getColumnIndex("text")));
comment.numLikes = c.getInt(c.getColumnIndex("num_likes"));
comment.isLikedByCurrentUser = SqlUtils.sqlToBool(c.getInt(c.getColumnIndex("is_liked")));
comment.pageNumber = c.getInt(c.getColumnIndex("page_number"));
return comment;
}
}