mirror of
https://github.com/TwidereProject/Twidere-Android
synced 2025-01-31 17:04:59 +01:00
fixed #188
moved query builder to a separate library try implementing dm and activities
This commit is contained in:
parent
817ac8e622
commit
6fbc782ce2
@ -1,11 +1,11 @@
|
||||
include ':twidere', ':twidere.extension.shortener.gist'
|
||||
include ':twidere'
|
||||
include ':twidere.component.common'
|
||||
include ':twidere.library.extension'
|
||||
include ':twidere.component.querybuilder'
|
||||
include ':twidere.wear'
|
||||
include ':twidere.donate.nyanwp'
|
||||
include ':twidere.donate.nyanwp.wear'
|
||||
include ':twidere.component.nyan'
|
||||
include ':twidere.extension.twitlonger'
|
||||
include ':twidere.extension.push.xiaomi'
|
||||
include ':twidere.extension.launcher.compose'
|
||||
include ':twidere.extension.launcher.compose'
|
||||
include ':twidere.extension.shortener.gist'
|
@ -43,8 +43,8 @@ dependencies {
|
||||
compile 'com.android.support:support-v4:22.2.0'
|
||||
compile 'com.bluelinelabs:logansquare:1.1.0'
|
||||
compile 'org.apache.commons:commons-lang3:3.4'
|
||||
compile 'com.github.mariotaku:RestFu:d965fcf941'
|
||||
compile 'com.github.mariotaku:RestFu:0.9'
|
||||
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1'
|
||||
compile project(':twidere.component.querybuilder')
|
||||
compile 'com.github.mariotaku:SQLiteQB:ef3f596199'
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
@ -19,11 +19,15 @@
|
||||
|
||||
package org.mariotaku.twidere.api.twitter.api;
|
||||
|
||||
import org.mariotaku.restfu.annotation.method.GET;
|
||||
import org.mariotaku.restfu.annotation.method.POST;
|
||||
import org.mariotaku.restfu.annotation.param.Body;
|
||||
import org.mariotaku.restfu.annotation.param.Path;
|
||||
import org.mariotaku.restfu.annotation.param.Query;
|
||||
import org.mariotaku.restfu.http.BodyType;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.PrivateDirectMessages;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseCode;
|
||||
|
||||
@SuppressWarnings("RedundantThrows")
|
||||
@ -37,4 +41,9 @@ public interface PrivateDirectMessagesResources extends PrivateResources {
|
||||
@Body(BodyType.FORM)
|
||||
ResponseCode destroyDirectMessagesConversation(@Path("account_id") long accountId, @Path("user_id") long userId) throws TwitterException;
|
||||
|
||||
@GET("/dm/user_updates.json")
|
||||
PrivateDirectMessages getUserUpdates(@Query Paging paging);
|
||||
|
||||
@GET("/dm/user_inbox.json")
|
||||
PrivateDirectMessages getUserInbox(@Query Paging paging);
|
||||
}
|
||||
|
@ -46,6 +46,10 @@ public class Paging extends SimpleValueMap {
|
||||
put("cursor", cursor);
|
||||
}
|
||||
|
||||
public void setCursor(String cursor) {
|
||||
put("cursor", cursor);
|
||||
}
|
||||
|
||||
public Paging sinceId(long sinceId) {
|
||||
setSinceId(sinceId);
|
||||
return this;
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.api.twitter.model;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/5.
|
||||
*/
|
||||
public interface PrivateDirectMessages {
|
||||
|
||||
UserEvents getUserEvents();
|
||||
|
||||
interface UserInbox {
|
||||
|
||||
User getUser(long userId);
|
||||
|
||||
Conversation getConversation(String conversationId);
|
||||
|
||||
Message[] getEntries();
|
||||
}
|
||||
|
||||
interface UserEvents {
|
||||
String getCursor();
|
||||
long getLastSeenEventId();
|
||||
}
|
||||
|
||||
UserInbox getUserInbox();
|
||||
|
||||
interface Message {
|
||||
interface Data extends EntitySupport {
|
||||
|
||||
String getText();
|
||||
|
||||
String getConversationId();
|
||||
|
||||
long getId();
|
||||
|
||||
long getRecipientId();
|
||||
|
||||
long getSenderId();
|
||||
|
||||
long getTime();
|
||||
}
|
||||
}
|
||||
|
||||
interface Conversation {
|
||||
Participant[] getParticipants();
|
||||
|
||||
String getConversationId();
|
||||
|
||||
long getLastReadEventId();
|
||||
|
||||
long getMaxEntryId();
|
||||
|
||||
long getMinEntryId();
|
||||
|
||||
boolean isNotificationsDisabled();
|
||||
|
||||
|
||||
interface Participant {
|
||||
|
||||
long getUserId();
|
||||
}
|
||||
|
||||
enum Type {
|
||||
ONE_TO_ONE, GROUP_DM
|
||||
}
|
||||
}
|
||||
|
||||
enum Status {
|
||||
HAS_MORE, AT_END
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.api.twitter.model.impl;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.model.HashtagEntity;
|
||||
import org.mariotaku.twidere.api.twitter.model.MediaEntity;
|
||||
import org.mariotaku.twidere.api.twitter.model.PrivateDirectMessages;
|
||||
import org.mariotaku.twidere.api.twitter.model.UrlEntity;
|
||||
import org.mariotaku.twidere.api.twitter.model.User;
|
||||
import org.mariotaku.twidere.api.twitter.model.UserMentionEntity;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/5.
|
||||
*/
|
||||
@JsonObject
|
||||
public class PrivateDirectMessagesImpl implements PrivateDirectMessages {
|
||||
|
||||
@JsonField(name = "user_inbox")
|
||||
UserInboxImpl userInbox;
|
||||
@JsonField(name = "user_events")
|
||||
UserEventsImpl userEvents;
|
||||
|
||||
@Override
|
||||
public UserInbox getUserInbox() {
|
||||
return userInbox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserEvents getUserEvents() {
|
||||
return userEvents;
|
||||
}
|
||||
|
||||
@JsonObject
|
||||
public static class UserInboxImpl implements UserInbox {
|
||||
|
||||
@JsonField(name = "users")
|
||||
Map<String, UserImpl> users;
|
||||
|
||||
@JsonField(name = "conversations")
|
||||
Map<String, ConversationImpl> conversations;
|
||||
|
||||
@JsonField(name = "entries")
|
||||
MessageImpl[] entries;
|
||||
|
||||
@Override
|
||||
public User getUser(long userId) {
|
||||
return users.get(String.valueOf(userId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Conversation getConversation(String conversationId) {
|
||||
return conversations.get(conversationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message[] getEntries() {
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@JsonObject
|
||||
public static class UserEventsImpl implements UserEvents {
|
||||
@JsonField(name = "cursor")
|
||||
String cursor;
|
||||
@JsonField(name = "last_seen_event_id")
|
||||
long lastSeenEventId;
|
||||
|
||||
@Override
|
||||
public String getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastSeenEventId() {
|
||||
return lastSeenEventId;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonObject
|
||||
public static class MessageImpl implements Message {
|
||||
|
||||
@JsonObject
|
||||
public static class DataImpl implements Data {
|
||||
|
||||
@Nullable
|
||||
@JsonField(name = "entities")
|
||||
EntitiesImpl entities;
|
||||
|
||||
@JsonField(name = "sender_id")
|
||||
long senderId;
|
||||
@JsonField(name = "recipient_id")
|
||||
long recipientId;
|
||||
@JsonField(name = "id")
|
||||
long id;
|
||||
@JsonField(name = "conversation_id")
|
||||
String conversationId;
|
||||
@JsonField(name = "text")
|
||||
String text;
|
||||
@JsonField(name = "time")
|
||||
long time;
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRecipientId() {
|
||||
return recipientId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSenderId() {
|
||||
return senderId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashtagEntity[] getHashtagEntities() {
|
||||
if (entities == null) return null;
|
||||
return entities.getHashtags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UrlEntity[] getUrlEntities() {
|
||||
if (entities == null) return null;
|
||||
return entities.getUrls();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaEntity[] getMediaEntities() {
|
||||
if (entities == null) return null;
|
||||
return entities.getMedia();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserMentionEntity[] getUserMentionEntities() {
|
||||
if (entities == null) return null;
|
||||
return entities.getUserMentions();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@JsonObject
|
||||
public static class ConversationImpl implements Conversation {
|
||||
|
||||
@JsonField(name = "conversation_id")
|
||||
String conversationId;
|
||||
@JsonField(name = "last_read_event_id")
|
||||
long lastReadEventId;
|
||||
@JsonField(name = "max_entry_id")
|
||||
long maxEntryId;
|
||||
@JsonField(name = "min_entry_id")
|
||||
long minEntryId;
|
||||
@JsonField(name = "notifications_disabled")
|
||||
boolean notificationsDisabled;
|
||||
@JsonField(name = "participants")
|
||||
ParticipantImpl[] participants;
|
||||
@JsonField(name = "read_only")
|
||||
boolean readOnly;
|
||||
@JsonField(name = "sort_event_id")
|
||||
long sortEventId;
|
||||
@JsonField(name = "sort_timestamp")
|
||||
long sortTimestamp;
|
||||
@JsonField(name = "status")
|
||||
Status status;
|
||||
@JsonField(name = "type")
|
||||
Type type;
|
||||
|
||||
@Override
|
||||
public Participant[] getParticipants() {
|
||||
return participants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConversationId() {
|
||||
return conversationId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastReadEventId() {
|
||||
return lastReadEventId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxEntryId() {
|
||||
return maxEntryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMinEntryId() {
|
||||
return minEntryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNotificationsDisabled() {
|
||||
return notificationsDisabled;
|
||||
}
|
||||
|
||||
@JsonObject
|
||||
public static class ParticipantImpl implements Participant {
|
||||
|
||||
@JsonField(name = "user_id")
|
||||
long userId;
|
||||
|
||||
@Override
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import java.util.AbstractList;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/5.
|
||||
*/
|
||||
public class ObjectCursor<E> extends AbstractList<E> {
|
||||
|
||||
private final Cursor mCursor;
|
||||
private final CursorIndices<E> mIndices;
|
||||
private final SparseArray<E> mCache;
|
||||
|
||||
public ObjectCursor(@NonNull Cursor cursor, @NonNull CursorIndices<E> indies) {
|
||||
mCursor = cursor;
|
||||
mIndices = indies;
|
||||
mCache = new SparseArray<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(final int location) {
|
||||
ensureCursor();
|
||||
final int idxOfCache = mCache.indexOfKey(location);
|
||||
if (idxOfCache >= 0) return mCache.valueAt(idxOfCache);
|
||||
if (mCursor.moveToPosition(location)) {
|
||||
final E object = get(mCursor, mIndices);
|
||||
mCache.put(location, object);
|
||||
return object;
|
||||
}
|
||||
throw new ArrayIndexOutOfBoundsException(location);
|
||||
}
|
||||
|
||||
private void ensureCursor() {
|
||||
if (mCursor.isClosed()) throw new IllegalStateException("Cursor is closed");
|
||||
}
|
||||
|
||||
protected E get(final Cursor cursor, final CursorIndices<E> indices) {
|
||||
return indices.newObject(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return mCursor.getCount();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return mCursor.isClosed();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
mCursor.close();
|
||||
}
|
||||
|
||||
public static abstract class CursorIndices<T> {
|
||||
|
||||
public CursorIndices(@NonNull Cursor cursor) {
|
||||
|
||||
}
|
||||
|
||||
abstract T newObject(Cursor cursor);
|
||||
}
|
||||
}
|
@ -32,9 +32,9 @@ import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.util.TwitterContentUtils;
|
||||
import org.mariotaku.twidere.util.content.ContentResolverUtils;
|
||||
|
@ -58,20 +58,9 @@ import java.util.Map.Entry;
|
||||
@ParcelablePlease(allFields = false)
|
||||
public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus> {
|
||||
|
||||
public static final Parcelable.Creator<ParcelableStatus> CREATOR = new Parcelable.Creator<ParcelableStatus>() {
|
||||
@Override
|
||||
public ParcelableStatus createFromParcel(final Parcel in) {
|
||||
ParcelableStatus status = new ParcelableStatus();
|
||||
ParcelableStatusParcelablePlease.readFromParcel(status, in);
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus[] newArray(final int size) {
|
||||
return new ParcelableStatus[size];
|
||||
}
|
||||
};
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "id")
|
||||
public long id;
|
||||
public static final Comparator<ParcelableStatus> REVERSE_ID_COMPARATOR = new Comparator<ParcelableStatus>() {
|
||||
|
||||
@Override
|
||||
@ -82,7 +71,12 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
return (int) diff;
|
||||
}
|
||||
};
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_id")
|
||||
public long account_id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "timestamp")
|
||||
public long timestamp;
|
||||
public static final Comparator<ParcelableStatus> TIMESTAMP_COMPARATOR = new Comparator<ParcelableStatus>() {
|
||||
|
||||
@Override
|
||||
@ -93,16 +87,6 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
return (int) diff;
|
||||
}
|
||||
};
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "id")
|
||||
public long id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_id")
|
||||
public long account_id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "timestamp")
|
||||
public long timestamp;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "user_id")
|
||||
public long user_id;
|
||||
@ -259,6 +243,19 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "card")
|
||||
public ParcelableCardEntity card;
|
||||
public static final Parcelable.Creator<ParcelableStatus> CREATOR = new Parcelable.Creator<ParcelableStatus>() {
|
||||
@Override
|
||||
public ParcelableStatus createFromParcel(final Parcel in) {
|
||||
ParcelableStatus status = new ParcelableStatus();
|
||||
ParcelableStatusParcelablePlease.readFromParcel(status, in);
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus[] newArray(final int size) {
|
||||
return new ParcelableStatus[size];
|
||||
}
|
||||
};
|
||||
|
||||
public ParcelableStatus(final Cursor c, final CursorIndices idx) {
|
||||
id = idx.status_id != -1 ? c.getLong(idx.status_id) : -1;
|
||||
@ -458,6 +455,16 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
card_name = card != null ? card.name : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPlaceFullName(@Nullable Place place) {
|
||||
if (place == null) return null;
|
||||
return place.getFullName();
|
||||
}
|
||||
|
||||
private static long getTime(final Date date) {
|
||||
return date != null ? date.getTime() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableStatus another) {
|
||||
final long diff = another.id - id;
|
||||
@ -550,17 +557,22 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
'}';
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPlaceFullName(@Nullable Place place) {
|
||||
if (place == null) return null;
|
||||
return place.getFullName();
|
||||
@Override
|
||||
public void writeToParcel(final Parcel out, final int flags) {
|
||||
ParcelableStatusParcelablePlease.writeToParcel(this, out, flags);
|
||||
}
|
||||
|
||||
private static long getTime(final Date date) {
|
||||
return date != null ? date.getTime() : 0;
|
||||
public static ParcelableStatus[] fromStatuses(Status[] statuses, long accountId) {
|
||||
if (statuses == null) return null;
|
||||
int size = statuses.length;
|
||||
final ParcelableStatus[] result = new ParcelableStatus[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
result[i] = new ParcelableStatus(statuses[i], accountId, false);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final class CursorIndices {
|
||||
public static final class CursorIndices extends ObjectCursor.CursorIndices<ParcelableStatus> {
|
||||
|
||||
public final int _id, account_id, status_id, status_timestamp, user_name, user_screen_name,
|
||||
text_html, text_plain, text_unescaped, user_profile_image_url, is_favorite, is_retweet,
|
||||
@ -575,6 +587,7 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
quoted_by_user_is_protected, quoted_by_user_is_verified;
|
||||
|
||||
public CursorIndices(final Cursor cursor) {
|
||||
super(cursor);
|
||||
_id = cursor.getColumnIndex(Statuses._ID);
|
||||
account_id = cursor.getColumnIndex(Statuses.ACCOUNT_ID);
|
||||
status_id = cursor.getColumnIndex(Statuses.STATUS_ID);
|
||||
@ -633,6 +646,11 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
place_full_name = cursor.getColumnIndex(Statuses.PLACE_FULL_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
ParcelableStatus newObject(Cursor cursor) {
|
||||
return new ParcelableStatus(cursor, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CursorIndices{" +
|
||||
@ -745,6 +763,25 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
values = ParcelableBindingValue.from(card.getBindingValues());
|
||||
}
|
||||
|
||||
public static ParcelableCardEntity fromCardEntity(CardEntity card, long account_id) {
|
||||
if (card == null) return null;
|
||||
return new ParcelableCardEntity(card, account_id);
|
||||
}
|
||||
|
||||
public static ParcelableCardEntity fromJSONString(final String json) {
|
||||
if (TextUtils.isEmpty(json)) return null;
|
||||
try {
|
||||
return LoganSquare.parse(json, ParcelableCardEntity.class);
|
||||
} catch (final IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ParcelableBindingValue getValue(@Nullable ParcelableCardEntity entity, @Nullable String key) {
|
||||
if (entity == null || entity.values == null || key == null) return null;
|
||||
return entity.values.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ParcelableCardEntity{" +
|
||||
@ -772,25 +809,6 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
dest.writeBundle(bundle);
|
||||
}
|
||||
|
||||
public static ParcelableCardEntity fromCardEntity(CardEntity card, long account_id) {
|
||||
if (card == null) return null;
|
||||
return new ParcelableCardEntity(card, account_id);
|
||||
}
|
||||
|
||||
public static ParcelableCardEntity fromJSONString(final String json) {
|
||||
if (TextUtils.isEmpty(json)) return null;
|
||||
try {
|
||||
return LoganSquare.parse(json, ParcelableCardEntity.class);
|
||||
} catch (final IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static ParcelableBindingValue getValue(@Nullable ParcelableCardEntity entity, @Nullable String key) {
|
||||
if (entity == null || entity.values == null || key == null) return null;
|
||||
return entity.values.get(key);
|
||||
}
|
||||
|
||||
@JsonObject
|
||||
public static final class ParcelableBindingValue implements Parcelable {
|
||||
|
||||
@ -835,11 +853,6 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Map<String, ParcelableBindingValue> from(Map<String, BindingValue> bindingValues) {
|
||||
if (bindingValues == null) return null;
|
||||
final Map<String, ParcelableBindingValue> map = new HashMap<>();
|
||||
@ -849,6 +862,11 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(type);
|
||||
@ -860,9 +878,4 @@ public class ParcelableStatus implements Parcelable, Comparable<ParcelableStatus
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(final Parcel out, final int flags) {
|
||||
ParcelableStatusParcelablePlease.writeToParcel(this, out, flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.database.Cursor;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
@ -360,33 +359,14 @@ public class ParcelableUser implements Parcelable, Comparable<ParcelableUser> {
|
||||
return new ParcelableUser(account_id, id, name, screen_name, profile_image_url);
|
||||
}
|
||||
|
||||
public static ContentValues makeCachedUserContentValues(final ParcelableUser user) {
|
||||
if (user == null) return null;
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(CachedUsers.USER_ID, user.id);
|
||||
values.put(CachedUsers.NAME, user.name);
|
||||
values.put(CachedUsers.SCREEN_NAME, user.screen_name);
|
||||
values.put(CachedUsers.PROFILE_IMAGE_URL, user.profile_image_url);
|
||||
values.put(CachedUsers.CREATED_AT, user.created_at);
|
||||
values.put(CachedUsers.IS_PROTECTED, user.is_protected);
|
||||
values.put(CachedUsers.IS_VERIFIED, user.is_verified);
|
||||
values.put(CachedUsers.LISTED_COUNT, user.listed_count);
|
||||
values.put(CachedUsers.FAVORITES_COUNT, user.favorites_count);
|
||||
values.put(CachedUsers.FOLLOWERS_COUNT, user.followers_count);
|
||||
values.put(CachedUsers.FRIENDS_COUNT, user.friends_count);
|
||||
values.put(CachedUsers.STATUSES_COUNT, user.statuses_count);
|
||||
values.put(CachedUsers.LOCATION, user.location);
|
||||
values.put(CachedUsers.DESCRIPTION_PLAIN, user.description_plain);
|
||||
values.put(CachedUsers.DESCRIPTION_HTML, user.description_html);
|
||||
values.put(CachedUsers.DESCRIPTION_EXPANDED, user.description_expanded);
|
||||
values.put(CachedUsers.URL, user.url);
|
||||
values.put(CachedUsers.URL_EXPANDED, user.url_expanded);
|
||||
values.put(CachedUsers.PROFILE_BANNER_URL, user.profile_banner_url);
|
||||
values.put(CachedUsers.IS_FOLLOWING, user.is_following);
|
||||
values.put(CachedUsers.BACKGROUND_COLOR, user.background_color);
|
||||
values.put(CachedUsers.LINK_COLOR, user.link_color);
|
||||
values.put(CachedUsers.TEXT_COLOR, user.text_color);
|
||||
return values;
|
||||
public static ParcelableUser[] fromUsers(final User[] users, long accountId) {
|
||||
if (users == null) return null;
|
||||
int size = users.length;
|
||||
final ParcelableUser[] result = new ParcelableUser[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
result[i] = new ParcelableUser(users[i], accountId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final class CachedIndices {
|
||||
|
@ -120,6 +120,16 @@ public class ParcelableUserList implements Parcelable, Comparable<ParcelableUser
|
||||
subscribers_count = list.getSubscriberCount();
|
||||
}
|
||||
|
||||
public static ParcelableUserList[] fromUserLists(UserList[] userLists, long accountId) {
|
||||
if (userLists == null) return null;
|
||||
int size = userLists.length;
|
||||
final ParcelableUserList[] result = new ParcelableUserList[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
result[i] = new ParcelableUserList(userLists[i], accountId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableUserList another) {
|
||||
final long diff = position - another.position;
|
||||
@ -178,5 +188,4 @@ public class ParcelableUserList implements Parcelable, Comparable<ParcelableUser
|
||||
out.writeLong(members_count);
|
||||
out.writeLong(subscribers_count);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -836,6 +836,38 @@ public interface TwidereDataStore {
|
||||
|
||||
}
|
||||
|
||||
interface Activities extends BaseColumns {
|
||||
|
||||
String ACCOUNT_ID = "account_id";
|
||||
String TIMESTAMP = "timestamp";
|
||||
String STATUS_USER_ID = "status_user_id";
|
||||
String STATUS_RETWEETED_BY_USER_ID = "status_retweeted_by_user_id";
|
||||
String STATUS_QUOTED_BY_USER_ID = "status_quoted_by_user_id";
|
||||
String STATUS_SOURCE = "status_source";
|
||||
String STATUS_QUOTE_SOURCE = "status_quote_source";
|
||||
String STATUS_TEXT_PLAIN = "status_text_plain";
|
||||
String STATUS_QUOTE_TEXT_PLAIN = "status_quote_text_plain";
|
||||
String STATUS_TEXT_HTML = "status_text_html";
|
||||
String STATUS_QUOTE_TEXT_HTML = "status_quote_text_html";
|
||||
String STATUS_IS_GAP = "status_is_gap";
|
||||
String MIN_POSITION = "min_position";
|
||||
String MAX_POSITION = "max_position";
|
||||
String SOURCES = "sources";
|
||||
String TARGET_STATUSES = "target_statuses";
|
||||
String TARGET_USERS = "target_users";
|
||||
String TARGET_USER_LISTS = "target_user_lists";
|
||||
String TARGET_OBJECT_STATUSES = "target_object_statuses";
|
||||
String TARGET_OBJECT_USER_LISTS = "target_object_user_lists";
|
||||
|
||||
}
|
||||
|
||||
interface ActivitiesAboutMe extends Activities {
|
||||
|
||||
String CONTENT_PATH = "activities_about_me";
|
||||
|
||||
Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, CONTENT_PATH);
|
||||
}
|
||||
|
||||
interface Tabs extends BaseColumns {
|
||||
String TABLE_NAME = "tabs";
|
||||
String CONTENT_PATH = TABLE_NAME;
|
||||
|
@ -29,6 +29,7 @@ import org.json.JSONObject;
|
||||
import org.mariotaku.twidere.TwidereConstants;
|
||||
import org.mariotaku.twidere.api.twitter.auth.OAuthAuthorization;
|
||||
import org.mariotaku.twidere.api.twitter.auth.OAuthToken;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
|
||||
import org.mariotaku.twidere.api.twitter.model.GeoLocation;
|
||||
import org.mariotaku.twidere.api.twitter.model.Place;
|
||||
@ -39,6 +40,7 @@ import org.mariotaku.twidere.api.twitter.model.Trend;
|
||||
import org.mariotaku.twidere.api.twitter.model.Trends;
|
||||
import org.mariotaku.twidere.api.twitter.model.UrlEntity;
|
||||
import org.mariotaku.twidere.api.twitter.model.User;
|
||||
import org.mariotaku.twidere.api.twitter.model.UserList;
|
||||
import org.mariotaku.twidere.model.ParcelableAccount;
|
||||
import org.mariotaku.twidere.model.ParcelableCredentials;
|
||||
import org.mariotaku.twidere.model.ParcelableDirectMessage;
|
||||
@ -51,6 +53,7 @@ import org.mariotaku.twidere.model.ParcelableStatusUpdate;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserMention;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
@ -394,7 +397,7 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
values.put(Statuses.IS_PROTECTED, user.isProtected());
|
||||
values.put(Statuses.IS_VERIFIED, user.isVerified());
|
||||
values.put(Statuses.USER_PROFILE_IMAGE_URL, profileImageUrl);
|
||||
values.put(CachedUsers.IS_FOLLOWING, user.isFollowing());
|
||||
values.put(Statuses.IS_FOLLOWING, user.isFollowing());
|
||||
final String textHtml = TwitterContentUtils.formatStatusText(status);
|
||||
values.put(Statuses.TEXT_HTML, textHtml);
|
||||
values.put(Statuses.TEXT_PLAIN, TwitterContentUtils.unescapeTwitterStatusText(status.getText()));
|
||||
@ -442,6 +445,71 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
return createStatusDraft(status, ParcelableAccount.getAccountIds(status.accounts));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ContentValues createActivity(final Activity activity, final long accountId) {
|
||||
final ContentValues values;
|
||||
switch (activity.getAction()) {
|
||||
case REPLY: {
|
||||
values = createStatusActivity(activity.getTargetStatuses()[0]);
|
||||
break;
|
||||
}
|
||||
case MENTION: {
|
||||
values = createStatusActivity(activity.getTargetObjectStatuses()[0]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
values = new ContentValues();
|
||||
break;
|
||||
}
|
||||
}
|
||||
values.put(Activities.ACCOUNT_ID, accountId);
|
||||
values.put(Activities.TIMESTAMP, activity.getCreatedAt().getTime());
|
||||
values.put(Activities.MIN_POSITION, activity.getMinPosition());
|
||||
values.put(Activities.MAX_POSITION, activity.getMaxPosition());
|
||||
values.put(Activities.SOURCES, SerializeUtils.serializeArray(User.class, activity.getSources()));
|
||||
values.put(Activities.TARGET_STATUSES, SerializeUtils.serializeArray(Status.class, activity.getTargetStatuses()));
|
||||
values.put(Activities.TARGET_USERS, SerializeUtils.serializeArray(User.class, activity.getTargetUsers()));
|
||||
values.put(Activities.TARGET_USER_LISTS, SerializeUtils.serializeArray(UserList.class, activity.getTargetUserLists()));
|
||||
values.put(Activities.TARGET_OBJECT_STATUSES, SerializeUtils.serializeArray(Status.class, activity.getTargetObjectStatuses()));
|
||||
values.put(Activities.TARGET_OBJECT_USER_LISTS, SerializeUtils.serializeArray(UserList.class, activity.getTargetObjectUserLists()));
|
||||
return values;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ContentValues createStatusActivity(final Status orig) {
|
||||
if (orig == null) throw new NullPointerException();
|
||||
final ContentValues values = new ContentValues();
|
||||
final Status status;
|
||||
if (orig.isRetweet()) {
|
||||
final Status retweetedStatus = orig.getRetweetedStatus();
|
||||
final User retweetUser = orig.getUser();
|
||||
final long retweetedById = retweetUser.getId();
|
||||
values.put(Activities.STATUS_RETWEETED_BY_USER_ID, retweetedById);
|
||||
status = retweetedStatus;
|
||||
} else if (orig.isQuote()) {
|
||||
final Status quotedStatus = orig.getQuotedStatus();
|
||||
final User quoteUser = orig.getUser();
|
||||
final long quotedById = quoteUser.getId();
|
||||
final String textHtml = TwitterContentUtils.formatStatusText(orig);
|
||||
values.put(Activities.STATUS_QUOTE_TEXT_HTML, textHtml);
|
||||
values.put(Activities.STATUS_QUOTE_TEXT_PLAIN, TwitterContentUtils.unescapeTwitterStatusText(orig.getText()));
|
||||
values.put(Activities.STATUS_QUOTE_SOURCE, orig.getSource());
|
||||
values.put(Activities.STATUS_QUOTED_BY_USER_ID, quotedById);
|
||||
status = quotedStatus;
|
||||
} else {
|
||||
status = orig;
|
||||
}
|
||||
final User user = status.getUser();
|
||||
final long userId = user.getId();
|
||||
values.put(Activities.STATUS_USER_ID, userId);
|
||||
final String textHtml = TwitterContentUtils.formatStatusText(status);
|
||||
values.put(Activities.STATUS_TEXT_HTML, textHtml);
|
||||
values.put(Activities.STATUS_TEXT_PLAIN, TwitterContentUtils.unescapeTwitterStatusText(status.getText()));
|
||||
values.put(Activities.STATUS_SOURCE, status.getSource());
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
public static ContentValues createStatusDraft(final ParcelableStatusUpdate status,
|
||||
final long[] accountIds) {
|
||||
final ContentValues values = new ContentValues();
|
||||
@ -476,4 +544,32 @@ public final class ContentValuesCreator implements TwidereConstants {
|
||||
return resultList.toArray(new ContentValues[resultList.size()]);
|
||||
}
|
||||
|
||||
public static ContentValues makeCachedUserContentValues(final ParcelableUser user) {
|
||||
if (user == null) return null;
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(CachedUsers.USER_ID, user.id);
|
||||
values.put(CachedUsers.NAME, user.name);
|
||||
values.put(CachedUsers.SCREEN_NAME, user.screen_name);
|
||||
values.put(CachedUsers.PROFILE_IMAGE_URL, user.profile_image_url);
|
||||
values.put(CachedUsers.CREATED_AT, user.created_at);
|
||||
values.put(CachedUsers.IS_PROTECTED, user.is_protected);
|
||||
values.put(CachedUsers.IS_VERIFIED, user.is_verified);
|
||||
values.put(CachedUsers.LISTED_COUNT, user.listed_count);
|
||||
values.put(CachedUsers.FAVORITES_COUNT, user.favorites_count);
|
||||
values.put(CachedUsers.FOLLOWERS_COUNT, user.followers_count);
|
||||
values.put(CachedUsers.FRIENDS_COUNT, user.friends_count);
|
||||
values.put(CachedUsers.STATUSES_COUNT, user.statuses_count);
|
||||
values.put(CachedUsers.LOCATION, user.location);
|
||||
values.put(CachedUsers.DESCRIPTION_PLAIN, user.description_plain);
|
||||
values.put(CachedUsers.DESCRIPTION_HTML, user.description_html);
|
||||
values.put(CachedUsers.DESCRIPTION_EXPANDED, user.description_expanded);
|
||||
values.put(CachedUsers.URL, user.url);
|
||||
values.put(CachedUsers.URL_EXPANDED, user.url_expanded);
|
||||
values.put(CachedUsers.PROFILE_BANNER_URL, user.profile_banner_url);
|
||||
values.put(CachedUsers.IS_FOLLOWING, user.is_following);
|
||||
values.put(CachedUsers.BACKGROUND_COLOR, user.background_color);
|
||||
values.put(CachedUsers.LINK_COLOR, user.link_color);
|
||||
values.put(CachedUsers.TEXT_COLOR, user.text_color);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
@ -17,24 +17,24 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: rootProject.file('global.gradle')
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
import com.bluelinelabs.logansquare.LoganSquare;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/7/6.
|
||||
*/
|
||||
public class SerializeUtils {
|
||||
|
||||
public static <T> String serializeArray(Class<T> cls, T... array) {
|
||||
try {
|
||||
return LoganSquare.serialize(Arrays.asList(array), cls);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
1
twidere.component.querybuilder/.gitignore
vendored
1
twidere.component.querybuilder/.gitignore
vendored
@ -1 +0,0 @@
|
||||
/build
|
@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /Users/mariotaku/Tools/android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twiderecomponentsqlquerybuilder;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<!--
|
||||
~ Twidere - Twitter client for Android
|
||||
~
|
||||
~ Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
~
|
||||
~ This program is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ This program is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
|
||||
<manifest package="org.mariotaku.querybuilder"/>
|
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class AllColumns implements Selectable {
|
||||
|
||||
private final String table;
|
||||
|
||||
public AllColumns() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public AllColumns(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return table != null ? table + ".*" : "*";
|
||||
}
|
||||
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class Columns implements Selectable {
|
||||
|
||||
private final AbsColumn[] columns;
|
||||
|
||||
public Columns(String... columns) {
|
||||
this(Columns.fromStrings(columns));
|
||||
}
|
||||
|
||||
public Columns(final AbsColumn... columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
private static Column[] fromStrings(String... columnsString) {
|
||||
final Column[] columns = new Column[columnsString.length];
|
||||
for (int i = 0, j = columnsString.length; i < j; i++) {
|
||||
columns[i] = new Column(columnsString[i]);
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return Utils.toString(columns, ',', true);
|
||||
}
|
||||
|
||||
public abstract static class AbsColumn implements Selectable {
|
||||
|
||||
}
|
||||
|
||||
public static class AllColumn extends AbsColumn {
|
||||
|
||||
private final Table table;
|
||||
|
||||
public AllColumn() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public AllColumn(final Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return table != null ? table.getSQL() + ".*" : "*";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Column extends AbsColumn {
|
||||
|
||||
private final Table table;
|
||||
private final String columnName, alias;
|
||||
|
||||
public Column(final String columnName) {
|
||||
this(null, columnName, null);
|
||||
}
|
||||
|
||||
public Column(final String columnName, final String alias) {
|
||||
this(null, columnName, alias);
|
||||
}
|
||||
|
||||
public Column(final Table table, final String columnName) {
|
||||
this(table, columnName, null);
|
||||
}
|
||||
|
||||
public Column(final Table table, final String columnName, final String alias) {
|
||||
if (columnName == null) throw new IllegalArgumentException("");
|
||||
this.table = table;
|
||||
this.columnName = columnName;
|
||||
this.alias = alias;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
final String col = table != null ? table.getSQL() + "." + columnName : columnName;
|
||||
return alias != null ? col + " AS " + alias : col;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/3/30.
|
||||
*/
|
||||
public class Constraint implements SQLLang {
|
||||
private final String name;
|
||||
private final String type;
|
||||
private final SQLQuery constraint;
|
||||
|
||||
public Constraint(String name, String type, SQLQuery constraint) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.constraint = constraint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
if (name != null) {
|
||||
sb.append("CONSTRAINT ");
|
||||
sb.append(name);
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(type);
|
||||
sb.append(" ");
|
||||
sb.append(constraint.getSQL());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static Constraint unique(String name, Columns columns, OnConflict onConflict) {
|
||||
return new Constraint(name, "UNIQUE", new ColumnConflictConstaint(columns, onConflict));
|
||||
}
|
||||
|
||||
public static Constraint unique(Columns columns, OnConflict onConflict) {
|
||||
return unique(null, columns, onConflict);
|
||||
}
|
||||
|
||||
private static final class ColumnConflictConstaint implements SQLQuery {
|
||||
|
||||
private final Columns columns;
|
||||
private final OnConflict onConflict;
|
||||
|
||||
public ColumnConflictConstaint(Columns columns, OnConflict onConflict) {
|
||||
this.columns = columns;
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("(");
|
||||
sb.append(columns.getSQL());
|
||||
sb.append(") ");
|
||||
sb.append("ON CONFLICT ");
|
||||
sb.append(onConflict.getAction());
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
* <p/>
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
* <p/>
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
* <p/>
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
* <p/>
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class Expression implements SQLLang {
|
||||
private final String expr;
|
||||
|
||||
public Expression(final String expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public Expression(SQLLang lang) {
|
||||
this(lang.getSQL());
|
||||
}
|
||||
|
||||
public static Expression and(final Expression... expressions) {
|
||||
return new Expression(toExpr(expressions, "AND"));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final Column r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = %s", l.getSQL(), r.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final Selectable r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = (%s)", l.getSQL(), r.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression equals(final String l, final Selectable r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = (%s)", l, r.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = %d", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Expression equals(final Column l, final String r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = '%s'", l.getSQL(), r));
|
||||
}
|
||||
|
||||
public static Expression equals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression greaterThan(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s > %d", l, r));
|
||||
}
|
||||
|
||||
|
||||
public static Expression greaterEquals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s >= %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression lesserEquals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s <= %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression lesserThan(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s < %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression in(final Column column, final Selectable in) {
|
||||
return new Expression(String.format("%s IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression notEquals(final String l, final long r) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s != %d", l, r));
|
||||
}
|
||||
|
||||
public static Expression notEquals(final String l, final String r) {
|
||||
return new Expression(String.format("%s != %s", l, r));
|
||||
}
|
||||
|
||||
public static Expression notIn(final Column column, final Selectable in) {
|
||||
return new Expression(String.format("%s NOT IN(%s)", column.getSQL(), in.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression notNull(final Column column) {
|
||||
return new Expression(String.format("%s NOT NULL", column.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression or(final Expression... expressions) {
|
||||
return new Expression(toExpr(expressions, "OR"));
|
||||
}
|
||||
|
||||
private static String toExpr(final Expression[] array, final String token) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append('(');
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i > 0) {
|
||||
builder.append(String.format(" %s ", token));
|
||||
}
|
||||
builder.append(array[i].getSQL());
|
||||
}
|
||||
builder.append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static Expression equalsArgs(String l) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s = ?", l));
|
||||
}
|
||||
|
||||
public static Expression isNull(Column column) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s IS NULL", column.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression greaterThan(Column column1, Column column2) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s > %s", column1.getSQL(), column2.getSQL()));
|
||||
}
|
||||
|
||||
public static Expression likeRaw(final Column column, final String pattern, final String escape) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s LIKE %s ESCAPE '%s'", column.getSQL(), pattern, escape));
|
||||
}
|
||||
|
||||
|
||||
public static Expression like(final Column column, final SQLLang expression) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s LIKE %s", column.getSQL(), expression.getSQL()));
|
||||
}
|
||||
|
||||
|
||||
public static Expression likeRaw(final Column column, final String pattern) {
|
||||
return new Expression(String.format(Locale.ROOT, "%s LIKE %s", column.getSQL(), pattern));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return expr;
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/12.
|
||||
*/
|
||||
public class Join implements SQLLang {
|
||||
|
||||
private final boolean natural;
|
||||
private final Operation operation;
|
||||
private final Selectable source;
|
||||
private final Expression on;
|
||||
|
||||
public Join(boolean natural, Operation operation, Selectable source, Expression on) {
|
||||
this.natural = natural;
|
||||
this.operation = operation;
|
||||
this.source = source;
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (operation == null) throw new IllegalArgumentException("operation can't be null!");
|
||||
if (source == null) throw new IllegalArgumentException("source can't be null!");
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
if (natural) {
|
||||
builder.append("NATURAL ");
|
||||
}
|
||||
builder.append(operation.getSQL());
|
||||
builder.append(" JOIN ");
|
||||
builder.append(source.getSQL());
|
||||
if (on != null) {
|
||||
builder.append(" ON ");
|
||||
builder.append(on.getSQL());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public enum Operation implements SQLLang {
|
||||
LEFT("LEFT"), LEFT_OUTER("LEFT OUTER"), INNER("INNER"), CROSS("CROSS");
|
||||
private final String op;
|
||||
|
||||
Operation(String op) {
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return op;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class NewColumn implements SQLLang {
|
||||
|
||||
private final String name;
|
||||
private final String type;
|
||||
|
||||
public NewColumn(final String name, final String type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static NewColumn[] createNewColumns(final String[] colNames, final String[] colTypes) {
|
||||
if (colNames == null || colTypes == null || colNames.length != colTypes.length)
|
||||
throw new IllegalArgumentException("length of columns and types not match.");
|
||||
final NewColumn[] newColumns = new NewColumn[colNames.length];
|
||||
for (int i = 0, j = colNames.length; i < j; i++) {
|
||||
newColumns[i] = new NewColumn(colNames[i], colTypes[i]);
|
||||
}
|
||||
return newColumns;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (name == null || type == null)
|
||||
throw new NullPointerException("name and type must not be null!");
|
||||
return String.format("%s %s", name, type);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-7.
|
||||
*/
|
||||
public enum OnConflict {
|
||||
ROLLBACK("ROLLBACK"), ABORT("ABORT"), REPLACE("REPLACE"), FAIL("FAIL"), IGNORE("IGNORE");
|
||||
private final String action;
|
||||
|
||||
OnConflict(final String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return action;
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
|
||||
public class OrderBy implements SQLLang {
|
||||
|
||||
private final String[] orderBy;
|
||||
private final boolean[] ascending;
|
||||
|
||||
public OrderBy(final String[] orderBy, final boolean[] ascending) {
|
||||
this.orderBy = orderBy;
|
||||
this.ascending = ascending;
|
||||
}
|
||||
|
||||
public OrderBy(final String... orderBy) {
|
||||
this(orderBy, null);
|
||||
}
|
||||
|
||||
public OrderBy(final String orderBy, final boolean ascending) {
|
||||
this.orderBy = new String[]{orderBy};
|
||||
this.ascending = new boolean[]{ascending};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0, j = orderBy.length; i < j; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(orderBy[i]);
|
||||
if (ascending != null) {
|
||||
sb.append(ascending[i] ? " ASC" : " DESC");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class RawItemArray implements Selectable {
|
||||
|
||||
private final Object[] array;
|
||||
|
||||
public RawItemArray(final long[] array) {
|
||||
final Long[] converted = new Long[array.length];
|
||||
for (int i = 0, j = array.length; i < j; i++) {
|
||||
converted[i] = array[i];
|
||||
}
|
||||
this.array = converted;
|
||||
}
|
||||
|
||||
public RawItemArray(final Object[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public RawItemArray(final int[] array) {
|
||||
final Integer[] converted = new Integer[array.length];
|
||||
for (int i = 0, j = array.length; i < j; i++) {
|
||||
converted[i] = array[i];
|
||||
}
|
||||
this.array = converted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return Utils.toString(array, ',', true);
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class SQLFunctions {
|
||||
|
||||
public static String SUM(final String val) {
|
||||
return String.format("SUM (%s)", val);
|
||||
}
|
||||
|
||||
public static String COUNT() {
|
||||
return COUNT("*");
|
||||
}
|
||||
|
||||
public static String COUNT(final String val) {
|
||||
return String.format("COUNT (%s)", val);
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public interface SQLLang extends Cloneable {
|
||||
|
||||
/**
|
||||
* Build SQL query string
|
||||
*
|
||||
* @return SQL query
|
||||
*/
|
||||
String getSQL();
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-6.
|
||||
*/
|
||||
public interface SQLQuery extends SQLLang {
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
* <p/>
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
* <p/>
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
* <p/>
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
* <p/>
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
import org.mariotaku.querybuilder.query.SQLAlterTableQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateIndexQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateTableQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateTriggerQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateViewQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLDeleteQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLDropTableQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLDropTriggerQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLDropViewQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLInsertQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLUpdateQuery;
|
||||
|
||||
public class SQLQueryBuilder {
|
||||
|
||||
private SQLQueryBuilder() {
|
||||
throw new AssertionError("You can't create instance for this class");
|
||||
}
|
||||
|
||||
public static SQLAlterTableQuery.Builder alterTable(final String table) {
|
||||
return new SQLAlterTableQuery.Builder().alterTable(table);
|
||||
}
|
||||
|
||||
public static SQLCreateTableQuery.Builder createTable(final boolean temporary, final boolean createIfNotExists,
|
||||
final String name) {
|
||||
return new SQLCreateTableQuery.Builder().createTable(temporary, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public static SQLCreateTableQuery.Builder createTable(final boolean createIfNotExists, final String name) {
|
||||
return createTable(false, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public static SQLCreateTableQuery.Builder createTable(final String name) {
|
||||
return createTable(false, false, name);
|
||||
}
|
||||
|
||||
public static SQLCreateViewQuery.Builder createView(final boolean temporary, final boolean createIfNotExists,
|
||||
final String name) {
|
||||
return new SQLCreateViewQuery.Builder().createView(temporary, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public static SQLCreateIndexQuery.Builder createIndex(final boolean unique, final boolean createIfNotExists) {
|
||||
return new SQLCreateIndexQuery.Builder().createIndex(unique, createIfNotExists);
|
||||
}
|
||||
|
||||
|
||||
public static SQLCreateTriggerQuery.Builder createTrigger(final boolean temporary, final boolean createIfNotExists,
|
||||
final String name) {
|
||||
return new SQLCreateTriggerQuery.Builder().createTrigger(temporary, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public static SQLCreateViewQuery.Builder createView(final boolean createIfNotExists, final String name) {
|
||||
return createView(false, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public static SQLCreateViewQuery.Builder createView(final String name) {
|
||||
return createView(false, false, name);
|
||||
}
|
||||
|
||||
public static SQLDeleteQuery.Builder deleteFrom(Table table) {
|
||||
return new SQLDeleteQuery.Builder().from(table);
|
||||
}
|
||||
|
||||
public static SQLDropTableQuery dropTable(final boolean dropIfExists, final String table) {
|
||||
return new SQLDropTableQuery(dropIfExists, table);
|
||||
}
|
||||
|
||||
public static SQLDropViewQuery dropView(final boolean dropIfExists, final String table) {
|
||||
return new SQLDropViewQuery(dropIfExists, table);
|
||||
}
|
||||
|
||||
public static SQLDropTriggerQuery dropTrigger(final boolean dropIfExists, final String table) {
|
||||
return new SQLDropTriggerQuery(dropIfExists, table);
|
||||
}
|
||||
|
||||
public static SQLInsertQuery.Builder insertInto(final OnConflict onConflict, final String table) {
|
||||
return new SQLInsertQuery.Builder().insertInto(onConflict, table);
|
||||
}
|
||||
|
||||
public static SQLUpdateQuery.Builder update(final OnConflict onConflict, final Table table) {
|
||||
return new SQLUpdateQuery.Builder().update(onConflict, table);
|
||||
}
|
||||
|
||||
public static SQLUpdateQuery.Builder update(final OnConflict onConflict, final String table) {
|
||||
return update(onConflict, new Table(table));
|
||||
}
|
||||
|
||||
public static SQLInsertQuery.Builder insertInto(final String table) {
|
||||
return insertInto(null, table);
|
||||
}
|
||||
|
||||
public static SQLSelectQuery.Builder select(final boolean distinct, final Selectable select) {
|
||||
return new SQLSelectQuery.Builder().select(distinct, select);
|
||||
}
|
||||
|
||||
public static SQLSelectQuery.Builder select(final Selectable select) {
|
||||
return select(false, select);
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class SQLQueryException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 910158450604676104L;
|
||||
|
||||
public SQLQueryException() {
|
||||
}
|
||||
|
||||
public SQLQueryException(final String detailMessage) {
|
||||
super(detailMessage);
|
||||
}
|
||||
|
||||
public SQLQueryException(final String detailMessage, final Throwable throwable) {
|
||||
super(detailMessage, throwable);
|
||||
}
|
||||
|
||||
public SQLQueryException(final Throwable throwable) {
|
||||
super(throwable);
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public interface Selectable extends SQLLang {
|
||||
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-7.
|
||||
*/
|
||||
public class SetValue implements SQLLang {
|
||||
|
||||
private final Columns.Column column;
|
||||
private final SQLLang expression;
|
||||
|
||||
public SetValue(Columns.Column column, SQLLang expression) {
|
||||
this.column = column;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public SetValue(String column, SQLLang expression) {
|
||||
this(new Columns.Column(column), expression);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return String.format(Locale.ROOT, "%s = %s", column.getSQL(), expression.getSQL());
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class Table implements Selectable {
|
||||
|
||||
public static final Table NEW = new Table("NEW");
|
||||
|
||||
private final String table;
|
||||
|
||||
public Table(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
* <p/>
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
* <p/>
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
* <p/>
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
* <p/>
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class Tables extends Table {
|
||||
|
||||
private final String[] tables;
|
||||
|
||||
public Tables(final String... tables) {
|
||||
super(null);
|
||||
this.tables = tables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return Utils.toString(tables, ',', true);
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
|
||||
public class Utils {
|
||||
|
||||
public static String toString(final Object[] array, final char token, final boolean includeSpace) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final int length = array.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String string = objectToString(array[i]);
|
||||
if (string != null) {
|
||||
if (i > 0) {
|
||||
builder.append(includeSpace ? token + " " : token);
|
||||
}
|
||||
builder.append(string);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String objectToString(Object o) {
|
||||
if (o instanceof SQLLang)
|
||||
return ((SQLLang) o).getSQL();
|
||||
return o != null ? o.toString() : null;
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.SQLLang;
|
||||
|
||||
public interface IBuilder<T extends SQLLang> {
|
||||
|
||||
public T build();
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #build()}.{@link SQLLang#getSQL()}
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String buildSQL();
|
||||
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.NewColumn;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
|
||||
public class SQLAlterTableQuery implements SQLQuery {
|
||||
|
||||
private String table;
|
||||
private String renameTo;
|
||||
private NewColumn addColumn;
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
if (renameTo == null && addColumn == null) throw new NullPointerException();
|
||||
if (renameTo != null) return String.format("ALTER TABLE %s RENAME TO %s", table, renameTo);
|
||||
return String.format("ALTER TABLE %s ADD COLUMN %s", table, addColumn.getSQL());
|
||||
}
|
||||
|
||||
void setAddColumn(final NewColumn addColumn) {
|
||||
this.addColumn = addColumn;
|
||||
}
|
||||
|
||||
void setRenameTo(final String renameTo) {
|
||||
this.renameTo = renameTo;
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLAlterTableQuery> {
|
||||
|
||||
private final SQLAlterTableQuery query = new SQLAlterTableQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder addColumn(final NewColumn addColumn) {
|
||||
checkNotBuilt();
|
||||
query.setAddColumn(addColumn);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder alterTable(final String table) {
|
||||
checkNotBuilt();
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLAlterTableQuery build() {
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder renameTo(final String renameTo) {
|
||||
checkNotBuilt();
|
||||
query.setRenameTo(renameTo);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
|
||||
public class SQLCreateIndexQuery implements SQLQuery {
|
||||
|
||||
private boolean unique;
|
||||
private boolean createIfNotExists;
|
||||
private Table table;
|
||||
private String indexName;
|
||||
private Columns indexedColumns;
|
||||
private Expression where;
|
||||
|
||||
SQLCreateIndexQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("Table must not be null!");
|
||||
if (indexName == null)
|
||||
throw new NullPointerException("SELECT statement must not be null!");
|
||||
final StringBuilder sb = new StringBuilder("CREATE");
|
||||
if (unique) {
|
||||
sb.append(" UNIQUE");
|
||||
}
|
||||
sb.append(" INDEX");
|
||||
if (createIfNotExists) {
|
||||
sb.append(" IF NOT EXISTS");
|
||||
}
|
||||
if (indexedColumns == null)
|
||||
throw new NullPointerException("Indexed columns must not be null !");
|
||||
sb.append(String.format(" %s ON %s (%s)", indexName, table.getSQL(), indexedColumns.getSQL()));
|
||||
if (where != null) {
|
||||
sb.append(" WHERE");
|
||||
sb.append(where.getSQL());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void setIndexedColumns(Columns indexedColumns) {
|
||||
this.indexedColumns = indexedColumns;
|
||||
}
|
||||
|
||||
public void setWhere(Expression where) {
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
void setIndexName(final String indexName) {
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||
this.createIfNotExists = createIfNotExists;
|
||||
}
|
||||
|
||||
void setTable(final Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
void setUnique(final boolean unique) {
|
||||
this.unique = unique;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLCreateIndexQuery> {
|
||||
|
||||
private final SQLCreateIndexQuery query = new SQLCreateIndexQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder on(final Table table, Columns indexedColumns) {
|
||||
checkNotBuilt();
|
||||
query.setTable(table);
|
||||
query.setIndexedColumns(indexedColumns);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder name(final String name) {
|
||||
checkNotBuilt();
|
||||
query.setIndexName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder where(final Expression expression) {
|
||||
checkNotBuilt();
|
||||
query.setWhere(expression);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public SQLCreateIndexQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
|
||||
public Builder createIndex(final boolean unique, final boolean createIfNotExists) {
|
||||
checkNotBuilt();
|
||||
query.setUnique(unique);
|
||||
query.setCreateIfNotExists(createIfNotExists);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Constraint;
|
||||
import org.mariotaku.querybuilder.NewColumn;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
public class SQLCreateTableQuery implements SQLQuery {
|
||||
|
||||
private boolean temporary;
|
||||
private boolean createIfNotExists;
|
||||
private String table;
|
||||
private NewColumn[] newColumns;
|
||||
private SQLSelectQuery selectStmt;
|
||||
private Constraint[] constraints;
|
||||
|
||||
SQLCreateTableQuery() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("NAME must not be null!");
|
||||
if ((newColumns == null || newColumns.length == 0) && selectStmt == null)
|
||||
throw new NullPointerException("Columns or AS must not be null!");
|
||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||
if (temporary) {
|
||||
sb.append("TEMPORARY ");
|
||||
}
|
||||
sb.append("TABLE ");
|
||||
if (createIfNotExists) {
|
||||
sb.append("IF NOT EXISTS ");
|
||||
}
|
||||
sb.append(table);
|
||||
sb.append(' ');
|
||||
if (newColumns != null && newColumns.length > 0) {
|
||||
sb.append('(');
|
||||
sb.append(Utils.toString(newColumns, ',', true));
|
||||
if (constraints != null && constraints.length > 0) {
|
||||
sb.append(", ");
|
||||
sb.append(Utils.toString(constraints, ',', true));
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(')');
|
||||
} else {
|
||||
sb.append("AS ");
|
||||
sb.append(selectStmt.getSQL());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setAs(final SQLSelectQuery selectStmt) {
|
||||
this.selectStmt = selectStmt;
|
||||
}
|
||||
|
||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||
this.createIfNotExists = createIfNotExists;
|
||||
}
|
||||
|
||||
void setNewColumns(final NewColumn[] newColumns) {
|
||||
this.newColumns = newColumns;
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
void setTemporary(final boolean temporary) {
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLCreateTableQuery> {
|
||||
|
||||
private final SQLCreateTableQuery query = new SQLCreateTableQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder as(final SQLSelectQuery selectStmt) {
|
||||
checkNotBuilt();
|
||||
query.setAs(selectStmt);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLCreateTableQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder columns(final NewColumn... newColumns) {
|
||||
checkNotBuilt();
|
||||
query.setNewColumns(newColumns);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder constraint(final Constraint... constraints) {
|
||||
checkNotBuilt();
|
||||
query.setConstraints(constraints);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder createTable(final boolean temporary, final boolean createIfNotExists, final String table) {
|
||||
checkNotBuilt();
|
||||
query.setTemporary(temporary);
|
||||
query.setCreateIfNotExists(createIfNotExists);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder createTable(final boolean createIfNotExists, final String table) {
|
||||
return createTable(false, createIfNotExists, table);
|
||||
}
|
||||
|
||||
public Builder createTemporaryTable(final boolean createIfNotExists, final String table) {
|
||||
return createTable(true, createIfNotExists, table);
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setConstraints(Constraint[] constraints) {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
}
|
@ -1,202 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.SQLLang;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14-8-6.
|
||||
*/
|
||||
public class SQLCreateTriggerQuery implements SQLQuery {
|
||||
|
||||
private boolean temporary;
|
||||
private boolean createIfNotExists;
|
||||
private boolean forEachRow;
|
||||
private String name;
|
||||
private Table on;
|
||||
private Type type;
|
||||
private Event event;
|
||||
private Columns updateOf;
|
||||
private SQLQuery[] actions;
|
||||
private Expression when;
|
||||
|
||||
void setActions(SQLQuery[] actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
void setForEachRow(boolean forEachRow) {
|
||||
this.forEachRow = forEachRow;
|
||||
}
|
||||
|
||||
void setOn(Table on) {
|
||||
this.on = on;
|
||||
}
|
||||
|
||||
void setUpdateOf(Columns updateOf) {
|
||||
this.updateOf = updateOf;
|
||||
}
|
||||
|
||||
void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
void setEvent(Event event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
void setWhen(Expression when) {
|
||||
this.when = when;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (name == null) throw new NullPointerException("NAME must not be null!");
|
||||
if (event == null) throw new NullPointerException("EVENT must not be null!");
|
||||
if (on == null) throw new NullPointerException("ON must not be null!");
|
||||
if (actions == null) throw new NullPointerException("ACTIONS must not be null!");
|
||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||
if (temporary) {
|
||||
sb.append("TEMPORARY ");
|
||||
}
|
||||
sb.append("TRIGGER ");
|
||||
if (createIfNotExists) {
|
||||
sb.append("IF NOT EXISTS ");
|
||||
}
|
||||
sb.append(name);
|
||||
sb.append(' ');
|
||||
if (type != null) {
|
||||
sb.append(type.getSQL());
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(event.getSQL());
|
||||
sb.append(' ');
|
||||
if (event == Event.UPDATE) {
|
||||
sb.append(String.format(Locale.ROOT, "%s ", updateOf.getSQL()));
|
||||
}
|
||||
sb.append(String.format(Locale.ROOT, "ON %s ", on.getSQL()));
|
||||
if (forEachRow) {
|
||||
sb.append("FOR EACH ROW ");
|
||||
}
|
||||
if (when != null) {
|
||||
sb.append(String.format(Locale.ROOT, "WHEN %s ", when.getSQL()));
|
||||
}
|
||||
sb.append(String.format(Locale.ROOT, "BEGIN %s; END", Utils.toString(actions, ';', true)));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||
this.createIfNotExists = createIfNotExists;
|
||||
}
|
||||
|
||||
void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
void setTemporary(final boolean temporary) {
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public static enum Type implements SQLLang {
|
||||
BEFORE("BEFORE"), AFTER("AFTER"), INSTEAD_OF("INSTEAD OF");
|
||||
private final String lang;
|
||||
|
||||
Type(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Event implements SQLLang {
|
||||
INSERT("INSERT"), DELETE("DELETE"), UPDATE("UPDATE");
|
||||
private final String lang;
|
||||
|
||||
Event(String lang) {
|
||||
this.lang = lang;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder implements IBuilder<SQLCreateTriggerQuery> {
|
||||
|
||||
private final SQLCreateTriggerQuery query = new SQLCreateTriggerQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder forEachRow(final boolean forEachRow) {
|
||||
checkNotBuilt();
|
||||
query.setForEachRow(forEachRow);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder on(final Table on) {
|
||||
checkNotBuilt();
|
||||
query.setOn(on);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder event(Event event) {
|
||||
checkNotBuilt();
|
||||
query.setEvent(event);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder type(Type type) {
|
||||
checkNotBuilt();
|
||||
query.setType(type);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder updateOf(Columns updateOf) {
|
||||
checkNotBuilt();
|
||||
query.setUpdateOf(updateOf);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder actions(SQLQuery... actions) {
|
||||
checkNotBuilt();
|
||||
query.setActions(actions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder when(Expression when) {
|
||||
checkNotBuilt();
|
||||
query.setWhen(when);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLCreateTriggerQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public Builder createTrigger(boolean temporary, boolean createIfNotExists, String name) {
|
||||
checkNotBuilt();
|
||||
query.setTemporary(temporary);
|
||||
query.setCreateIfNotExists(createIfNotExists);
|
||||
query.setName(name);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
|
||||
public class SQLCreateViewQuery implements SQLQuery {
|
||||
|
||||
private boolean temporary;
|
||||
private boolean createIfNotExists;
|
||||
private String name;
|
||||
private SQLSelectQuery selectStmt;
|
||||
|
||||
SQLCreateViewQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (name == null) throw new NullPointerException("NAME must not be null!");
|
||||
if (selectStmt == null)
|
||||
throw new NullPointerException("SELECT statement must not be null!");
|
||||
final StringBuilder sb = new StringBuilder("CREATE ");
|
||||
if (temporary) {
|
||||
sb.append("TEMPORARY ");
|
||||
}
|
||||
sb.append("VIEW ");
|
||||
if (createIfNotExists) {
|
||||
sb.append("IF NOT EXISTS ");
|
||||
}
|
||||
sb.append(String.format("%s AS %s", name, selectStmt.getSQL()));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setAs(final SQLSelectQuery selectStmt) {
|
||||
this.selectStmt = selectStmt;
|
||||
}
|
||||
|
||||
void setCreateIfNotExists(final boolean createIfNotExists) {
|
||||
this.createIfNotExists = createIfNotExists;
|
||||
}
|
||||
|
||||
void setName(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
void setTemporary(final boolean temporary) {
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLCreateViewQuery> {
|
||||
|
||||
private final SQLCreateViewQuery query = new SQLCreateViewQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
public Builder as(final SQLSelectQuery selectStmt) {
|
||||
checkNotBuilt();
|
||||
query.setAs(selectStmt);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLCreateViewQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder createTemporaryView(final boolean createIfNotExists, final String name) {
|
||||
return createView(true, createIfNotExists, name);
|
||||
}
|
||||
|
||||
public Builder createView(final boolean temporary, final boolean createIfNotExists, final String name) {
|
||||
checkNotBuilt();
|
||||
query.setTemporary(temporary);
|
||||
query.setCreateIfNotExists(createIfNotExists);
|
||||
query.setName(name);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder createView(final boolean createIfNotExists, final String name) {
|
||||
return createView(false, createIfNotExists, name);
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
|
||||
public class SQLDeleteQuery implements SQLQuery {
|
||||
|
||||
private Table table;
|
||||
private Expression where;
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (where == null) return String.format("DELETE FROM %s", table.getSQL());
|
||||
return String.format("DELETE FROM %S WHERE %s", table.getSQL(), where.getSQL());
|
||||
}
|
||||
|
||||
void setFrom(final Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
void setWhere(final Expression where) {
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLDeleteQuery> {
|
||||
private final SQLDeleteQuery query = new SQLDeleteQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLDeleteQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder from(final Table table) {
|
||||
checkNotBuilt();
|
||||
query.setFrom(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder where(final Expression where) {
|
||||
checkNotBuilt();
|
||||
query.setWhere(where);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
|
||||
public class SQLDropQuery implements SQLQuery {
|
||||
|
||||
private final boolean dropIfExists;
|
||||
private final String type;
|
||||
private final String target;
|
||||
|
||||
public SQLDropQuery(final boolean dropIfExists, final String type, final String target) {
|
||||
if (target == null) throw new NullPointerException();
|
||||
this.dropIfExists = dropIfExists;
|
||||
this.type = type;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSQL() {
|
||||
if (dropIfExists) return String.format("DROP %s IF EXISTS %s", type, target);
|
||||
return String.format("DROP %s %s", type, target);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
public class SQLDropTableQuery extends SQLDropQuery {
|
||||
|
||||
public SQLDropTableQuery(final boolean dropIfExists, final String table) {
|
||||
super(dropIfExists, "TABLE", table);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
public class SQLDropTriggerQuery extends SQLDropQuery {
|
||||
|
||||
public SQLDropTriggerQuery(final boolean dropIfExists, final String table) {
|
||||
super(dropIfExists, "TRIGGER", table);
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
public class SQLDropViewQuery extends SQLDropQuery {
|
||||
|
||||
public SQLDropViewQuery(final boolean dropIfExists, final String table) {
|
||||
super(dropIfExists, "VIEW", table);
|
||||
}
|
||||
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
public class SQLInsertQuery implements SQLQuery {
|
||||
|
||||
private OnConflict onConflict;
|
||||
private String table;
|
||||
private String[] columns;
|
||||
private String values;
|
||||
|
||||
SQLInsertQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("INSERT ");
|
||||
if (onConflict != null) {
|
||||
sb.append("OR ");
|
||||
sb.append(onConflict.getAction());
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append("INTO ");
|
||||
sb.append(table);
|
||||
sb.append(" (");
|
||||
sb.append(Utils.toString(columns, ',', true));
|
||||
sb.append(") ");
|
||||
sb.append(values);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setColumns(final String[] columns) {
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
void setOnConflict(final OnConflict onConflict) {
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
void setSelect(final SQLSelectQuery select) {
|
||||
this.values = select.getSQL();
|
||||
}
|
||||
|
||||
void setValues(final String... values) {
|
||||
this.values = "VALUES (" + Utils.toString(values, ',', true) + ")";
|
||||
}
|
||||
|
||||
void setTable(final String table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLInsertQuery> {
|
||||
|
||||
private final SQLInsertQuery query = new SQLInsertQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLInsertQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder columns(final String[] columns) {
|
||||
checkNotBuilt();
|
||||
query.setColumns(columns);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder values(final String[] values) {
|
||||
checkNotBuilt();
|
||||
query.setValues(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder values(final String values) {
|
||||
checkNotBuilt();
|
||||
query.setValues(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final OnConflict onConflict, final String table) {
|
||||
checkNotBuilt();
|
||||
query.setOnConflict(onConflict);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder insertInto(final String table) {
|
||||
return insertInto(null, table);
|
||||
}
|
||||
|
||||
public Builder select(final SQLSelectQuery select) {
|
||||
checkNotBuilt();
|
||||
query.setSelect(select);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,280 +0,0 @@
|
||||
/**
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.Join;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.SQLLang;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.SQLQueryException;
|
||||
import org.mariotaku.querybuilder.Selectable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SQLSelectQuery implements SQLQuery, Selectable {
|
||||
|
||||
private final List<InternalQuery> internalQueries = new ArrayList<>();
|
||||
|
||||
private InternalQuery currentInternalQuery;
|
||||
private OrderBy orderBy;
|
||||
private Integer limit = null, offset = null;
|
||||
|
||||
SQLSelectQuery() {
|
||||
initCurrentQuery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final int size = internalQueries.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (i != 0) {
|
||||
sb.append("UNION ");
|
||||
}
|
||||
final InternalQuery query = internalQueries.get(i);
|
||||
sb.append(query.getSQL());
|
||||
}
|
||||
if (orderBy != null) {
|
||||
sb.append(String.format("ORDER BY %s ", orderBy.getSQL()));
|
||||
}
|
||||
if (limit != null) {
|
||||
sb.append(String.format("LIMIT %s ", limit));
|
||||
if (offset != null) {
|
||||
sb.append(String.format("OFFSET %s ", offset));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void initCurrentQuery() {
|
||||
currentInternalQuery = new InternalQuery();
|
||||
internalQueries.add(currentInternalQuery);
|
||||
}
|
||||
|
||||
void setDistinct(final boolean distinct) {
|
||||
currentInternalQuery.setDistinct(distinct);
|
||||
}
|
||||
|
||||
void setFrom(final Selectable from) {
|
||||
currentInternalQuery.setFrom(from);
|
||||
}
|
||||
|
||||
void setGroupBy(final Selectable groupBy) {
|
||||
currentInternalQuery.setGroupBy(groupBy);
|
||||
}
|
||||
|
||||
void setHaving(final Expression having) {
|
||||
currentInternalQuery.setHaving(having);
|
||||
}
|
||||
|
||||
void setJoin(final Join join) {
|
||||
currentInternalQuery.setJoin(join);
|
||||
}
|
||||
|
||||
void setLimit(final int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
void setOffset(final int offset) {
|
||||
this.offset = offset;
|
||||
}
|
||||
|
||||
void setOrderBy(final OrderBy orderBy) {
|
||||
this.orderBy = orderBy;
|
||||
}
|
||||
|
||||
void setSelect(final Selectable select) {
|
||||
currentInternalQuery.setSelect(select);
|
||||
}
|
||||
|
||||
void setWhere(final Expression where) {
|
||||
currentInternalQuery.setWhere(where);
|
||||
}
|
||||
|
||||
void union() {
|
||||
initCurrentQuery();
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLSelectQuery> {
|
||||
private final SQLSelectQuery query = new SQLSelectQuery();
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLSelectQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder from(final Selectable from) {
|
||||
checkNotBuilt();
|
||||
query.setFrom(from);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder groupBy(final Selectable groupBy) {
|
||||
checkNotBuilt();
|
||||
query.setGroupBy(groupBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder having(final Expression having) {
|
||||
checkNotBuilt();
|
||||
query.setHaving(having);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public Builder limit(final int limit) {
|
||||
checkNotBuilt();
|
||||
query.setLimit(limit);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder join(final Join join) {
|
||||
checkNotBuilt();
|
||||
query.setJoin(join);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder offset(final int offset) {
|
||||
query.setOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder orderBy(final OrderBy orderBy) {
|
||||
checkNotBuilt();
|
||||
query.setOrderBy(orderBy);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder select(final boolean distinct, final Selectable select) {
|
||||
checkNotBuilt();
|
||||
query.setSelect(select);
|
||||
query.setDistinct(distinct);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder select(final Selectable select) {
|
||||
checkNotBuilt();
|
||||
select(false, select);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder union() {
|
||||
checkNotBuilt();
|
||||
query.union();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder where(final Expression where) {
|
||||
checkNotBuilt();
|
||||
query.setWhere(where);
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class InternalQuery implements SQLLang {
|
||||
|
||||
private boolean distinct;
|
||||
private Selectable select, from, groupBy;
|
||||
private Expression where, having;
|
||||
private Join join;
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (select == null) throw new SQLQueryException("selectable is null");
|
||||
final StringBuilder sb = new StringBuilder("SELECT ");
|
||||
if (distinct) {
|
||||
sb.append("DISTINCT ");
|
||||
}
|
||||
sb.append(String.format("%s ", select.getSQL()));
|
||||
if (!(select instanceof SQLSelectQuery) && from == null)
|
||||
throw new SQLQueryException("FROM not specified");
|
||||
else if (from != null) {
|
||||
if (from instanceof SQLSelectQuery) {
|
||||
sb.append(String.format("FROM (%s) ", from.getSQL()));
|
||||
} else {
|
||||
sb.append(String.format("FROM %s ", from.getSQL()));
|
||||
}
|
||||
}
|
||||
if (join != null) {
|
||||
sb.append(String.format("%s ", join.getSQL()));
|
||||
}
|
||||
if (where != null) {
|
||||
sb.append(String.format("WHERE %s ", where.getSQL()));
|
||||
}
|
||||
if (groupBy != null) {
|
||||
sb.append(String.format("GROUP BY %s ", groupBy.getSQL()));
|
||||
if (having != null) {
|
||||
sb.append(String.format("HAVING %s ", having.getSQL()));
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setJoin(final Join join) {
|
||||
this.join = join;
|
||||
}
|
||||
|
||||
void setDistinct(final boolean distinct) {
|
||||
this.distinct = distinct;
|
||||
}
|
||||
|
||||
void setFrom(final Selectable from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
void setGroupBy(final Selectable groupBy) {
|
||||
this.groupBy = groupBy;
|
||||
}
|
||||
|
||||
void setHaving(final Expression having) {
|
||||
this.having = having;
|
||||
}
|
||||
|
||||
void setSelect(final Selectable select) {
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
void setWhere(final Expression where) {
|
||||
this.where = where;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
package org.mariotaku.querybuilder.query;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.SetValue;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.Utils;
|
||||
|
||||
public class SQLUpdateQuery implements SQLQuery {
|
||||
|
||||
private OnConflict onConflict;
|
||||
private Table table;
|
||||
private SetValue[] values;
|
||||
private Expression where;
|
||||
|
||||
SQLUpdateQuery() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
if (table == null) throw new NullPointerException("table must not be null!");
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("UPDATE ");
|
||||
if (onConflict != null) {
|
||||
sb.append("OR ");
|
||||
sb.append(onConflict.getAction());
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(table.getSQL());
|
||||
sb.append(" SET ");
|
||||
sb.append(Utils.toString(values, ',', true));
|
||||
if (where != null) {
|
||||
sb.append(" WHERE ");
|
||||
sb.append(where.getSQL());
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void setWhere(final Expression where) {
|
||||
this.where = where;
|
||||
}
|
||||
|
||||
void setValues(final SetValue[] columns) {
|
||||
this.values = columns;
|
||||
}
|
||||
|
||||
void setOnConflict(final OnConflict onConflict) {
|
||||
this.onConflict = onConflict;
|
||||
}
|
||||
|
||||
void setTable(final Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
public static final class Builder implements IBuilder<SQLUpdateQuery> {
|
||||
|
||||
private final SQLUpdateQuery query = new SQLUpdateQuery();
|
||||
|
||||
private boolean buildCalled;
|
||||
|
||||
@Override
|
||||
public SQLUpdateQuery build() {
|
||||
buildCalled = true;
|
||||
return query;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String buildSQL() {
|
||||
return build().getSQL();
|
||||
}
|
||||
|
||||
public Builder set(final SetValue... values) {
|
||||
checkNotBuilt();
|
||||
query.setValues(values);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder where(final Expression where) {
|
||||
checkNotBuilt();
|
||||
query.setWhere(where);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder update(final OnConflict onConflict, final Table table) {
|
||||
checkNotBuilt();
|
||||
query.setOnConflict(onConflict);
|
||||
query.setTable(table);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder update(final Table table) {
|
||||
return update(null, table);
|
||||
}
|
||||
|
||||
private void checkNotBuilt() {
|
||||
if (buildCalled) throw new IllegalStateException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -90,7 +90,7 @@ dependencies {
|
||||
compile 'com.makeramen:roundedimageview:2.1.0'
|
||||
compile 'com.soundcloud.android:android-crop:1.0.0@aar'
|
||||
compile 'com.hannesdorfmann.parcelableplease:annotation:1.0.1'
|
||||
compile 'com.github.mariotaku:PickNCrop:b8322f8e3c'
|
||||
compile 'com.github.mariotaku:PickNCrop:44b09cbc69'
|
||||
compile 'com.diogobernardino:williamchart:1.7.0'
|
||||
googleCompile 'com.google.android.gms:play-services-maps:7.5.0'
|
||||
googleCompile 'com.google.maps.android:android-maps-utils:0.3.4'
|
||||
|
@ -17,21 +17,13 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.querybuilder;
|
||||
package android.support.v4.content;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/6/24.
|
||||
* Created by mariotaku on 15/7/5.
|
||||
*/
|
||||
public final class RawSQLLang implements SQLLang {
|
||||
|
||||
private final String statement;
|
||||
|
||||
public RawSQLLang(String statement) {
|
||||
this.statement = statement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return statement;
|
||||
public class LoaderTrojan {
|
||||
public static <T> boolean isContentChanged(final Loader<T> loader) {
|
||||
return loader.mContentChanged;
|
||||
}
|
||||
}
|
@ -53,10 +53,10 @@ import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.QuickSearchBarActivity.SuggestionItem;
|
||||
import org.mariotaku.twidere.adapter.AccountsSpinnerAdapter;
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2014 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.view.holder.StatusViewHolder;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 14/11/19.
|
||||
*/
|
||||
public class CursorStatusesAdapter extends AbsStatusesAdapter<Cursor> {
|
||||
|
||||
private Cursor mCursor;
|
||||
private CursorIndices mIndices;
|
||||
|
||||
public CursorStatusesAdapter(Context context, boolean compact) {
|
||||
super(context, compact);
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGapItem(int position) {
|
||||
final Cursor c = mCursor;
|
||||
if (c == null || !c.moveToPosition(position) || position == getStatusesCount() - 1)
|
||||
return false;
|
||||
return c.getInt(mIndices.is_gap) == 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (position == getStatusesCount()) return Long.MAX_VALUE;
|
||||
final Cursor c = mCursor;
|
||||
if (c != null && c.moveToPosition(position)) {
|
||||
return c.getLong(mIndices._id);
|
||||
}
|
||||
return RecyclerView.NO_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindStatus(StatusViewHolder holder, int position) {
|
||||
mCursor.moveToPosition(position);
|
||||
holder.displayStatus(mCursor, mIndices, isShowInReplyTo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableStatus getStatus(int position) {
|
||||
if (isLoadMoreIndicatorVisible() && position == getStatusesCount() - 1) return null;
|
||||
final Cursor c = mCursor;
|
||||
if (c != null && c.moveToPosition(position)) {
|
||||
return new ParcelableStatus(c, mIndices);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStatusesCount() {
|
||||
if (mCursor == null) return 0;
|
||||
return mCursor.getCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getStatusId(int position) {
|
||||
if (position == getStatusesCount()) return -1;
|
||||
final Cursor c = mCursor;
|
||||
if (c != null && c.moveToPosition(position)) {
|
||||
return c.getLong(mIndices.status_id);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(Cursor data) {
|
||||
mCursor = data;
|
||||
mIndices = data != null ? new CursorIndices(data) : null;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cursor getData() {
|
||||
return mCursor;
|
||||
}
|
||||
}
|
@ -32,10 +32,10 @@ import android.widget.EditText;
|
||||
import android.widget.FilterQueryProvider;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
|
@ -54,9 +54,9 @@ import android.widget.ListView;
|
||||
import android.widget.SimpleCursorAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.UserListSelectorActivity;
|
||||
import org.mariotaku.twidere.adapter.SourceAutoCompleteAdapter;
|
||||
|
@ -55,9 +55,9 @@ import com.mobeta.android.dslv.DragSortListView;
|
||||
import com.mobeta.android.dslv.DragSortListView.DropListener;
|
||||
import com.mobeta.android.dslv.SimpleDragSortCursorAdapter;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.SettingsActivity;
|
||||
import org.mariotaku.twidere.activity.support.CustomTabEditorActivity;
|
||||
|
@ -77,7 +77,7 @@ import com.commonsware.cwac.merge.MergeAdapter;
|
||||
import com.nostra13.universalimageloader.core.assist.FailReason;
|
||||
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.SettingsActivity;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
|
@ -35,7 +35,7 @@ import android.widget.TextView;
|
||||
import com.mobeta.android.dslv.DragSortListView;
|
||||
import com.mobeta.android.dslv.DragSortListView.DropListener;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.ColorPickerDialogActivity;
|
||||
import org.mariotaku.twidere.activity.support.SignInActivity;
|
||||
|
@ -23,7 +23,6 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
@ -35,14 +34,15 @@ import com.desmond.asyncmanager.AsyncManager;
|
||||
import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
import org.mariotaku.twidere.adapter.AbsStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||
import org.mariotaku.twidere.loader.support.ExtendedCursorLoader;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.loader.support.ObjectCursorLoader;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Filters;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses;
|
||||
@ -55,6 +55,8 @@ import org.mariotaku.twidere.util.message.StatusDestroyedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusListChangedEvent;
|
||||
import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.mariotaku.twidere.util.Utils.buildStatusFilterWhereClause;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getOldestStatusIdsFromDatabase;
|
||||
@ -63,12 +65,12 @@ import static org.mariotaku.twidere.util.Utils.getTableNameByUri;
|
||||
/**
|
||||
* Created by mariotaku on 14/12/3.
|
||||
*/
|
||||
public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor> {
|
||||
public abstract class CursorStatusesFragment extends AbsStatusesFragment<List<ParcelableStatus>> {
|
||||
|
||||
@Override
|
||||
protected void onLoadingFinished() {
|
||||
final long[] accountIds = getAccountIds();
|
||||
final AbsStatusesAdapter<Cursor> adapter = getAdapter();
|
||||
final AbsStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||
if (adapter.getItemCount() > 0) {
|
||||
showContent();
|
||||
} else if (accountIds.length > 0) {
|
||||
@ -84,9 +86,9 @@ public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor>
|
||||
public abstract Uri getContentUri();
|
||||
|
||||
@Override
|
||||
protected Loader<Cursor> onCreateStatusesLoader(final Context context,
|
||||
final Bundle args,
|
||||
final boolean fromUser) {
|
||||
protected Loader<List<ParcelableStatus>> onCreateStatusesLoader(final Context context,
|
||||
final Bundle args,
|
||||
final boolean fromUser) {
|
||||
final Uri uri = getContentUri();
|
||||
final String table = getTableNameByUri(uri);
|
||||
final String sortOrder = getSortOrder();
|
||||
@ -99,10 +101,11 @@ public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor>
|
||||
where = accountWhere;
|
||||
}
|
||||
final String selection = processWhere(where).getSQL();
|
||||
final AbsStatusesAdapter<Cursor> adapter = getAdapter();
|
||||
final AbsStatusesAdapter<List<ParcelableStatus>> adapter = getAdapter();
|
||||
adapter.setShowAccountsColor(accountIds.length > 1);
|
||||
final String[] projection = Statuses.COLUMNS;
|
||||
return new ExtendedCursorLoader(context, uri, projection, selection, null, sortOrder, fromUser);
|
||||
return new ObjectCursorLoader<>(context, ParcelableStatus.CursorIndices.class, uri, projection,
|
||||
selection, null, sortOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -198,18 +201,18 @@ public abstract class CursorStatusesFragment extends AbsStatusesFragment<Cursor>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasMoreData(final Cursor cursor) {
|
||||
return cursor != null && cursor.getCount() != 0;
|
||||
protected boolean hasMoreData(final List<ParcelableStatus> cursor) {
|
||||
return cursor != null && cursor.size() != 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected CursorStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new CursorStatusesAdapter(context, compact);
|
||||
protected ParcelableStatusesAdapter onCreateAdapter(final Context context, final boolean compact) {
|
||||
return new ParcelableStatusesAdapter(context, compact);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
public void onLoaderReset(Loader<List<ParcelableStatus>> loader) {
|
||||
getAdapter().setData(null);
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,9 @@ import android.view.View;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity;
|
||||
import org.mariotaku.twidere.activity.support.HomeActivity;
|
||||
|
@ -56,9 +56,9 @@ import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.DraftsAdapter;
|
||||
|
@ -25,7 +25,7 @@ import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
|
||||
import org.mariotaku.twidere.adapter.CursorStatusesAdapter;
|
||||
import org.mariotaku.twidere.adapter.ParcelableStatusesAdapter;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Mentions;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
|
||||
@ -41,8 +41,8 @@ public class MentionsTimelineFragment extends CursorStatusesFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected CursorStatusesAdapter onCreateAdapter(Context context, boolean compact) {
|
||||
final CursorStatusesAdapter adapter = super.onCreateAdapter(context, compact);
|
||||
protected ParcelableStatusesAdapter onCreateAdapter(Context context, boolean compact) {
|
||||
final ParcelableStatusesAdapter adapter = super.onCreateAdapter(context, compact);
|
||||
adapter.setShowInReplyTo(false);
|
||||
return adapter;
|
||||
}
|
||||
|
@ -71,10 +71,10 @@ import com.github.johnpersano.supertoasts.SuperToast.OnDismissListener;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.support.BaseAppCompatActivity;
|
||||
import org.mariotaku.twidere.activity.support.ThemedImagePickerActivity;
|
||||
@ -113,7 +113,6 @@ import org.mariotaku.twidere.util.UserColorNameManager;
|
||||
import org.mariotaku.twidere.util.Utils;
|
||||
import org.mariotaku.twidere.util.message.TaskStateChangedEvent;
|
||||
import org.mariotaku.twidere.view.ComposeEditText;
|
||||
import org.mariotaku.twidere.view.ComposeMaterialEditText;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -388,6 +387,7 @@ public class MessagesConversationFragment extends BaseSupportFragment implements
|
||||
public void onStop() {
|
||||
mMessagesListView.removeOnScrollListener(mScrollListener);
|
||||
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.unregister(this);
|
||||
if (mPopupMenu != null) {
|
||||
mPopupMenu.dismiss();
|
||||
|
@ -83,6 +83,7 @@ public abstract class ParcelableStatusesFragment extends AbsStatusesFragment<Lis
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
final Bus bus = TwidereApplication.getInstance(getActivity()).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.register(this);
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,12 @@ import com.commonsware.cwac.merge.MergeAdapter;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
|
||||
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelState;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.SQLQueryBuilder;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
|
||||
import org.mariotaku.sqliteqb.library.Table;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.adapter.TrendsAdapter;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedTrends;
|
||||
|
@ -32,7 +32,6 @@ import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@ -86,7 +85,7 @@ import com.meizu.flyme.reflect.StatusBarProxy;
|
||||
import com.squareup.otto.Bus;
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.activity.iface.IThemedActivity;
|
||||
import org.mariotaku.twidere.activity.support.AccountSelectorActivity;
|
||||
@ -294,7 +293,7 @@ public class UserFragment extends BaseSupportFragment implements OnClickListener
|
||||
mFollowingYouIndicator.setVisibility(relationship.isTargetFollowingSource() ? View.VISIBLE : View.GONE);
|
||||
|
||||
final ContentResolver resolver = getContentResolver();
|
||||
final ContentValues cachedValues = ParcelableUser.makeCachedUserContentValues(user);
|
||||
final ContentValues cachedValues = ContentValuesCreator.makeCachedUserContentValues(user);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, cachedValues);
|
||||
mFollowButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.loader.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import org.mariotaku.twidere.loader.iface.IExtendedLoader;
|
||||
import org.mariotaku.twidere.model.ObjectCursor;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15/1/9.
|
||||
*/
|
||||
public class ExtendedObjectCursorLoader<E> extends ObjectCursorLoader<E> implements IExtendedLoader {
|
||||
|
||||
public ExtendedObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<E>> indicesClass) {
|
||||
super(context, indicesClass);
|
||||
}
|
||||
|
||||
public ExtendedObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<E>> indicesClass,
|
||||
Uri uri, String[] projection, String selection, String[] selectionArgs,
|
||||
String sortOrder, boolean fromUser) {
|
||||
super(context, indicesClass, uri, projection, selection, selectionArgs, sortOrder);
|
||||
setFromUser(fromUser);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFromUser() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFromUser(boolean fromUser) {
|
||||
//No-op
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,249 @@
|
||||
/*
|
||||
* Twidere - Twitter client for Android
|
||||
*
|
||||
* Copyright (C) 2012-2015 Mariotaku Lee <mariotaku.lee@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.mariotaku.twidere.loader.support;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.support.v4.content.LoaderTrojan;
|
||||
|
||||
import org.mariotaku.twidere.model.ObjectCursor;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by mariotaku on 15-7-5.
|
||||
*/
|
||||
public class ObjectCursorLoader<T> extends AsyncTaskLoader<List<T>> {
|
||||
|
||||
final ForceLoadContentObserver mObserver;
|
||||
final Class<? extends ObjectCursor.CursorIndices<T>> mIndicesClass;
|
||||
|
||||
Uri mUri;
|
||||
String[] mProjection;
|
||||
String mSelection;
|
||||
String[] mSelectionArgs;
|
||||
String mSortOrder;
|
||||
|
||||
ObjectCursor<T> mObjects;
|
||||
|
||||
/* Runs on a worker thread */
|
||||
@Override
|
||||
public ObjectCursor<T> loadInBackground() {
|
||||
Cursor cursor = getContext().getContentResolver().query(mUri, mProjection, mSelection,
|
||||
mSelectionArgs, mSortOrder);
|
||||
if (cursor != null) {
|
||||
// Ensure the cursor window is filled
|
||||
cursor.getCount();
|
||||
cursor.registerContentObserver(mObserver);
|
||||
}
|
||||
if (cursor == null) throw new NullPointerException("Cursor is null");
|
||||
return new ObjectCursor<>(cursor, createIndices(cursor));
|
||||
}
|
||||
|
||||
@SuppressWarnings("TryWithIdenticalCatches")
|
||||
@NonNull
|
||||
private ObjectCursor.CursorIndices<T> createIndices(final Cursor cursor) {
|
||||
try {
|
||||
return mIndicesClass.getConstructor(Cursor.class).newInstance(cursor);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InstantiationException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* Runs on the UI thread */
|
||||
@Override
|
||||
public void deliverResult(List<T> data) {
|
||||
final ObjectCursor<T> cursor = (ObjectCursor<T>) data;
|
||||
if (isReset()) {
|
||||
// An async query came in while the loader is stopped
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
return;
|
||||
}
|
||||
ObjectCursor<T> oldCursor = mObjects;
|
||||
mObjects = cursor;
|
||||
|
||||
if (isStarted()) {
|
||||
super.deliverResult(cursor);
|
||||
}
|
||||
|
||||
if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
|
||||
oldCursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty unspecified CursorLoader. You must follow this with
|
||||
* calls to {@link #setUri(Uri)}, {@link #setSelection(String)}, etc
|
||||
* to specify the query to perform.
|
||||
*/
|
||||
public ObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<T>> indicesClass) {
|
||||
super(context);
|
||||
mIndicesClass = indicesClass;
|
||||
mObserver = new ForceLoadContentObserver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fully-specified CursorLoader. See
|
||||
* {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)
|
||||
* ContentResolver.query()} for documentation on the meaning of the
|
||||
* parameters. These will be passed as-is to that call.
|
||||
*/
|
||||
public ObjectCursorLoader(Context context, Class<? extends ObjectCursor.CursorIndices<T>> indicesClass,
|
||||
Uri uri, String[] projection, String selection,
|
||||
String[] selectionArgs, String sortOrder) {
|
||||
super(context);
|
||||
mIndicesClass = indicesClass;
|
||||
mObserver = new ForceLoadContentObserver();
|
||||
mUri = uri;
|
||||
mProjection = projection;
|
||||
mSelection = selection;
|
||||
mSelectionArgs = selectionArgs;
|
||||
mSortOrder = sortOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts an asynchronous load of the contacts list data. When the result is ready the callbacks
|
||||
* will be called on the UI thread. If a previous load has been completed and is still valid
|
||||
* the result may be passed to the callbacks immediately.
|
||||
* <p/>
|
||||
* Must be called from the UI thread
|
||||
*/
|
||||
@Override
|
||||
protected void onStartLoading() {
|
||||
if (mObjects != null) {
|
||||
deliverResult(mObjects);
|
||||
}
|
||||
if (takeContentChanged() || mObjects == null) {
|
||||
forceLoad();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called from the UI thread
|
||||
*/
|
||||
@Override
|
||||
protected void onStopLoading() {
|
||||
// Attempt to cancel the current load task if possible.
|
||||
cancelLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCanceled(List<T> data) {
|
||||
final ObjectCursor<T> cursor = (ObjectCursor<T>) data;
|
||||
if (cursor != null && !cursor.isClosed()) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onReset() {
|
||||
super.onReset();
|
||||
|
||||
// Ensure the loader is stopped
|
||||
onStopLoading();
|
||||
|
||||
if (mObjects != null && !mObjects.isClosed()) {
|
||||
mObjects.close();
|
||||
}
|
||||
mObjects = null;
|
||||
}
|
||||
|
||||
public Uri getUri() {
|
||||
return mUri;
|
||||
}
|
||||
|
||||
public void setUri(Uri uri) {
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
public String[] getProjection() {
|
||||
return mProjection;
|
||||
}
|
||||
|
||||
public void setProjection(String[] projection) {
|
||||
mProjection = projection;
|
||||
}
|
||||
|
||||
public String getSelection() {
|
||||
return mSelection;
|
||||
}
|
||||
|
||||
public void setSelection(String selection) {
|
||||
mSelection = selection;
|
||||
}
|
||||
|
||||
public String[] getSelectionArgs() {
|
||||
return mSelectionArgs;
|
||||
}
|
||||
|
||||
public void setSelectionArgs(String[] selectionArgs) {
|
||||
mSelectionArgs = selectionArgs;
|
||||
}
|
||||
|
||||
public String getSortOrder() {
|
||||
return mSortOrder;
|
||||
}
|
||||
|
||||
public void setSortOrder(String sortOrder) {
|
||||
mSortOrder = sortOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
|
||||
super.dump(prefix, fd, writer, args);
|
||||
writer.print(prefix);
|
||||
writer.print("mUri=");
|
||||
writer.println(mUri);
|
||||
writer.print(prefix);
|
||||
writer.print("mProjection=");
|
||||
writer.println(Arrays.toString(mProjection));
|
||||
writer.print(prefix);
|
||||
writer.print("mSelection=");
|
||||
writer.println(mSelection);
|
||||
writer.print(prefix);
|
||||
writer.print("mSelectionArgs=");
|
||||
writer.println(Arrays.toString(mSelectionArgs));
|
||||
writer.print(prefix);
|
||||
writer.print("mSortOrder=");
|
||||
writer.println(mSortOrder);
|
||||
writer.print(prefix);
|
||||
writer.print("mObjects=");
|
||||
writer.println(mObjects);
|
||||
writer.print(prefix);
|
||||
writer.print("mContentChanged=");
|
||||
writer.println(LoaderTrojan.isContentChanged(this));
|
||||
}
|
||||
|
||||
}
|
@ -56,7 +56,7 @@ public abstract class ParcelableActivitiesLoader extends AsyncTaskLoader<List<Pa
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean deleteStatus(final List<ParcelableActivity> activities, final long id) {
|
||||
protected boolean deleteActivity(final List<ParcelableActivity> activities, final long id) {
|
||||
if (activities == null || activities.isEmpty()) return false;
|
||||
boolean result = false;
|
||||
for (final ParcelableActivity activity : activities.toArray(new ParcelableActivity[activities.size()])) {
|
||||
|
@ -27,13 +27,14 @@ import android.os.Bundle;
|
||||
import android.support.v4.content.AsyncTaskLoader;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUser.CachedIndices;
|
||||
import org.mariotaku.twidere.model.SingleResponse;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.util.ContentValuesCreator;
|
||||
import org.mariotaku.twidere.util.TwitterAPIFactory;
|
||||
import org.mariotaku.twidere.util.TwitterWrapper;
|
||||
|
||||
@ -71,7 +72,7 @@ public final class ParcelableUserLoader extends AsyncTaskLoader<SingleResponse<P
|
||||
if (!mOmitIntentExtra && mExtras != null) {
|
||||
final ParcelableUser user = mExtras.getParcelable(EXTRA_USER);
|
||||
if (user != null) {
|
||||
final ContentValues values = ParcelableUser.makeCachedUserContentValues(user);
|
||||
final ContentValues values = ContentValuesCreator.makeCachedUserContentValues(user);
|
||||
resolver.insert(CachedUsers.CONTENT_URI, values);
|
||||
return SingleResponse.getInstance(user);
|
||||
}
|
||||
|
@ -104,27 +104,27 @@ public abstract class TwitterAPIActivitiesLoader extends ParcelableActivitiesLoa
|
||||
e.printStackTrace();
|
||||
return new CopyOnWriteArrayList<>(data);
|
||||
}
|
||||
final Pair<Long, Long> minId;
|
||||
final Pair<Long, Long> position;
|
||||
if (activities.isEmpty()) {
|
||||
minId = new Pair<>(-1L, -1L);
|
||||
position = new Pair<>(-1L, -1L);
|
||||
} else {
|
||||
final Activity minActivity = Collections.min(activities);
|
||||
minId = new Pair<>(minActivity.getMinPosition(), minActivity.getMaxPosition());
|
||||
position = new Pair<>(minActivity.getMinPosition(), minActivity.getMaxPosition());
|
||||
}
|
||||
final boolean insertGap = minId.first > 0 && minId.second > 0 && activities.size() > 1
|
||||
final boolean insertGap = position.first > 0 && position.second > 0 && activities.size() > 1
|
||||
&& !data.isEmpty() && !truncated;
|
||||
// mHandler.post(CacheUsersStatusesTask.getRunnable(context, new StatusListResponse(mAccountIds, activities)));
|
||||
for (final Activity activity : activities) {
|
||||
final long min = activity.getMinPosition(), max = activity.getMaxPosition();
|
||||
final boolean deleted = deleteStatus(data, max);
|
||||
final boolean isGap = minId.first == min && minId.second == max && insertGap && !deleted;
|
||||
final boolean deleted = deleteActivity(data, max);
|
||||
final boolean isGap = position.first == min && position.second == max && insertGap && !deleted;
|
||||
data.add(new ParcelableActivity(activity, mAccountIds, isGap));
|
||||
}
|
||||
// final ParcelableActivity[] array = data.toArray(new ParcelableActivity[data.size()]);
|
||||
// for (int i = 0, size = array.length; i < size; i++) {
|
||||
// final ParcelableActivity status = array[i];
|
||||
// if (shouldFilterActivity(mDatabase, status) && !status.is_gap && i != size - 1) {
|
||||
// deleteStatus(data, status.max_position);
|
||||
// deleteActivity(data, status.max_position);
|
||||
// }
|
||||
// }
|
||||
if (mComparator != null) {
|
||||
|
@ -23,9 +23,9 @@ import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.NetworkUsages;
|
||||
import org.mariotaku.twidere.util.MathUtils;
|
||||
|
||||
|
@ -19,20 +19,22 @@
|
||||
|
||||
package org.mariotaku.twidere.model;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.bluelinelabs.logansquare.annotation.JsonField;
|
||||
import com.bluelinelabs.logansquare.annotation.JsonObject;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelablePlease;
|
||||
import com.hannesdorfmann.parcelableplease.annotation.ParcelableThisPlease;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.Status;
|
||||
import org.mariotaku.twidere.api.twitter.model.User;
|
||||
import org.mariotaku.twidere.api.twitter.model.UserList;
|
||||
|
||||
@ParcelablePlease(allFields = false)
|
||||
@JsonObject
|
||||
public class ParcelableActivity implements Comparable<ParcelableActivity> {
|
||||
public class ParcelableActivity implements Comparable<ParcelableActivity>, Parcelable {
|
||||
|
||||
public final static int ACTION_FAVORITE = Activity.Action.ACTION_FAVORITE;
|
||||
public final static int ACTION_FOLLOW = Activity.Action.ACTION_FOLLOW;
|
||||
@ -44,30 +46,54 @@ public class ParcelableActivity implements Comparable<ParcelableActivity> {
|
||||
public final static int ACTION_FAVORITED_RETWEET = Activity.Action.ACTION_FAVORITED_RETWEET;
|
||||
public final static int ACTION_RETWEETED_RETWEET = Activity.Action.ACTION_RETWEETED_RETWEET;
|
||||
|
||||
public static final Creator<ParcelableActivity> CREATOR = new Creator<ParcelableActivity>() {
|
||||
@Override
|
||||
public ParcelableActivity createFromParcel(Parcel source) {
|
||||
return new ParcelableActivity(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelableActivity[] newArray(int size) {
|
||||
return new ParcelableActivity[size];
|
||||
}
|
||||
};
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "account_id")
|
||||
public long account_id;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "timestamp")
|
||||
public long timestamp;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "max_position")
|
||||
public long max_position;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "min_position")
|
||||
public long min_position;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "action")
|
||||
public int action;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "sources")
|
||||
public ParcelableUser[] sources;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "target_users")
|
||||
public ParcelableUser[] target_users;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "target_statuses")
|
||||
public ParcelableStatus[] target_statuses;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "target_user_lists")
|
||||
public ParcelableUserList[] target_user_lists;
|
||||
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "target_object_user_lists")
|
||||
public ParcelableUserList[] target_object_user_lists;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "target_object_statuses")
|
||||
public ParcelableStatus[] target_object_statuses;
|
||||
@ParcelableThisPlease
|
||||
@JsonField(name = "is_gap")
|
||||
public boolean is_gap;
|
||||
|
||||
@ -80,61 +106,19 @@ public class ParcelableActivity implements Comparable<ParcelableActivity> {
|
||||
action = activity.getAction().getActionId();
|
||||
max_position = activity.getMaxPosition();
|
||||
min_position = activity.getMinPosition();
|
||||
final int sources_size = activity.getSourcesSize();
|
||||
sources = new ParcelableUser[sources_size];
|
||||
for (int i = 0; i < sources_size; i++) {
|
||||
sources[i] = new ParcelableUser(activity.getSources()[i], account_id);
|
||||
}
|
||||
final int targets_size = activity.getTargetsSize();
|
||||
final User[] targetUsers = activity.getTargetUsers();
|
||||
if (targetUsers != null) {
|
||||
target_users = new ParcelableUser[targets_size];
|
||||
for (int i = 0; i < targets_size; i++) {
|
||||
target_users[i] = new ParcelableUser(targetUsers[i], account_id);
|
||||
}
|
||||
} else {
|
||||
target_users = null;
|
||||
}
|
||||
final UserList[] targetUserLists = activity.getTargetUserLists();
|
||||
if (targetUserLists != null) {
|
||||
target_user_lists = new ParcelableUserList[targets_size];
|
||||
for (int i = 0; i < targets_size; i++) {
|
||||
target_user_lists[i] = new ParcelableUserList(targetUserLists[i], account_id);
|
||||
}
|
||||
} else {
|
||||
target_user_lists = null;
|
||||
}
|
||||
final Status[] targetStatuses = activity.getTargetStatuses();
|
||||
if (targetStatuses != null) {
|
||||
target_statuses = new ParcelableStatus[targets_size];
|
||||
for (int i = 0; i < targets_size; i++) {
|
||||
target_statuses[i] = new ParcelableStatus(targetStatuses[i], account_id, false);
|
||||
}
|
||||
} else {
|
||||
target_statuses = null;
|
||||
}
|
||||
final int target_objects_size = activity.getTargetObjectsSize();
|
||||
final Status[] targetObjectStatuses = activity.getTargetObjectStatuses();
|
||||
if (targetObjectStatuses != null) {
|
||||
target_object_statuses = new ParcelableStatus[target_objects_size];
|
||||
for (int i = 0; i < target_objects_size; i++) {
|
||||
target_object_statuses[i] = new ParcelableStatus(targetObjectStatuses[i], account_id, false);
|
||||
}
|
||||
} else {
|
||||
target_object_statuses = null;
|
||||
}
|
||||
final UserList[] targetObjectUserLists = activity.getTargetObjectUserLists();
|
||||
if (targetObjectUserLists != null) {
|
||||
target_object_user_lists = new ParcelableUserList[target_objects_size];
|
||||
for (int i = 0; i < target_objects_size; i++) {
|
||||
target_object_user_lists[i] = new ParcelableUserList(targetObjectUserLists[i], account_id);
|
||||
}
|
||||
} else {
|
||||
target_object_user_lists = null;
|
||||
}
|
||||
sources = ParcelableUser.fromUsers(activity.getSources(), account_id);
|
||||
target_users = ParcelableUser.fromUsers(activity.getTargetUsers(), account_id);
|
||||
target_user_lists = ParcelableUserList.fromUserLists(activity.getTargetUserLists(), account_id);
|
||||
target_statuses = ParcelableStatus.fromStatuses(activity.getTargetStatuses(), account_id);
|
||||
target_object_statuses = ParcelableStatus.fromStatuses(activity.getTargetObjectStatuses(), account_id);
|
||||
target_object_user_lists = ParcelableUserList.fromUserLists(activity.getTargetObjectUserLists(), account_id);
|
||||
this.is_gap = is_gap;
|
||||
}
|
||||
|
||||
public ParcelableActivity(Parcel src) {
|
||||
ParcelableActivityParcelablePlease.readFromParcel(this, src);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int compareTo(@NonNull final ParcelableActivity another) {
|
||||
@ -163,4 +147,13 @@ public class ParcelableActivity implements Comparable<ParcelableActivity> {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
ParcelableActivityParcelablePlease.writeToParcel(this, dest, flags);
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.provider.BaseColumns;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.NotificationCompat.InboxStyle;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
@ -60,16 +61,16 @@ import com.squareup.okhttp.internal.Network;
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.RawSQLLang;
|
||||
import org.mariotaku.querybuilder.SQLQueryBuilder;
|
||||
import org.mariotaku.querybuilder.SetValue;
|
||||
import org.mariotaku.querybuilder.query.SQLInsertQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLUpdateQuery;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OnConflict;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.RawSQLLang;
|
||||
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
|
||||
import org.mariotaku.sqliteqb.library.SetValue;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLInsertQuery;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLUpdateQuery;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.R;
|
||||
@ -136,7 +137,10 @@ public final class TwidereDataProvider extends ContentProvider implements Consta
|
||||
private ContentResolver mContentResolver;
|
||||
private SQLiteDatabaseWrapper mDatabaseWrapper;
|
||||
private PermissionsManager mPermissionsManager;
|
||||
|
||||
@Nullable
|
||||
private NotificationManager mNotificationManager;
|
||||
|
||||
private ReadStateManager mReadStateManager;
|
||||
private SharedPreferencesWrapper mPreferences;
|
||||
private ImagePreloader mImagePreloader;
|
||||
|
@ -44,7 +44,7 @@ import android.widget.Toast;
|
||||
import com.nostra13.universalimageloader.utils.IoUtils;
|
||||
import com.twitter.Extractor;
|
||||
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.restfu.http.ContentType;
|
||||
import org.mariotaku.restfu.http.mime.FileTypedData;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
|
@ -31,6 +31,7 @@ import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.desmond.asyncmanager.AsyncManager;
|
||||
import com.desmond.asyncmanager.BackgroundTask;
|
||||
@ -38,15 +39,16 @@ import com.desmond.asyncmanager.TaskRunnable;
|
||||
import com.squareup.otto.Bus;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.SQLFunctions;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.SQLFunctions;
|
||||
import org.mariotaku.twidere.BuildConfig;
|
||||
import org.mariotaku.twidere.R;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.http.HttpResponseCode;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
|
||||
import org.mariotaku.twidere.api.twitter.model.FriendshipUpdate;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
@ -98,6 +100,7 @@ import org.mariotaku.twidere.util.message.StatusRetweetedEvent;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@ -106,21 +109,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import edu.tsinghua.spice.Utilies.SpiceProfilingUtil;
|
||||
import edu.tsinghua.spice.Utilies.TypeMappingUtil;
|
||||
|
||||
import static org.mariotaku.twidere.provider.TwidereDataStore.STATUSES_URIS;
|
||||
import static org.mariotaku.twidere.util.ContentValuesCreator.createDirectMessage;
|
||||
import static org.mariotaku.twidere.util.ContentValuesCreator.createStatus;
|
||||
import static org.mariotaku.twidere.util.ContentValuesCreator.createTrends;
|
||||
import static org.mariotaku.twidere.util.Utils.getActivatedAccountIds;
|
||||
import static org.mariotaku.twidere.util.Utils.getDefaultAccountId;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestMessageIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getNewestStatusIdsFromDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.getStatusCountInDatabase;
|
||||
import static org.mariotaku.twidere.util.Utils.showErrorMessage;
|
||||
import static org.mariotaku.twidere.util.Utils.showInfoMessage;
|
||||
import static org.mariotaku.twidere.util.Utils.showOkMessage;
|
||||
import static org.mariotaku.twidere.util.content.ContentResolverUtils.bulkDelete;
|
||||
import static org.mariotaku.twidere.util.content.ContentResolverUtils.bulkInsert;
|
||||
|
||||
public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
private final Context mContext;
|
||||
@ -410,7 +398,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
@Deprecated
|
||||
public void refreshAll() {
|
||||
refreshAll(getActivatedAccountIds(mContext));
|
||||
refreshAll(Utils.getActivatedAccountIds(mContext));
|
||||
}
|
||||
|
||||
public boolean refreshAll(final long[] accountIds) {
|
||||
@ -420,16 +408,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final Object[] result = new Object[8];
|
||||
result[0] = mPreferences.getBoolean(KEY_HOME_REFRESH_MENTIONS);
|
||||
if (Boolean.TRUE.equals(result[0] = mPreferences.getBoolean(KEY_HOME_REFRESH_MENTIONS))) {
|
||||
result[1] = getNewestStatusIdsFromDatabase(mContext, Mentions.CONTENT_URI, accountIds);
|
||||
result[1] = Utils.getNewestStatusIdsFromDatabase(mContext, Mentions.CONTENT_URI, accountIds);
|
||||
}
|
||||
if (Boolean.TRUE.equals(result[2] = mPreferences.getBoolean(KEY_HOME_REFRESH_DIRECT_MESSAGES))) {
|
||||
result[3] = getNewestMessageIdsFromDatabase(mContext, DirectMessages.Inbox.CONTENT_URI, accountIds);
|
||||
result[3] = Utils.getNewestMessageIdsFromDatabase(mContext, DirectMessages.Inbox.CONTENT_URI, accountIds);
|
||||
}
|
||||
if (Boolean.TRUE.equals(result[4] = mPreferences.getBoolean(KEY_HOME_REFRESH_TRENDS))) {
|
||||
result[5] = getDefaultAccountId(mContext);
|
||||
result[5] = Utils.getDefaultAccountId(mContext);
|
||||
result[6] = mPreferences.getInt(KEY_LOCAL_TRENDS_WOEID, 1);
|
||||
}
|
||||
result[7] = getNewestStatusIdsFromDatabase(mContext, Statuses.CONTENT_URI, accountIds);
|
||||
result[7] = Utils.getNewestStatusIdsFromDatabase(mContext, Statuses.CONTENT_URI, accountIds);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -598,12 +586,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
|
||||
super.onPostExecute(result);
|
||||
if (result.hasData()) {
|
||||
showOkMessage(mContext, R.string.profile_banner_image_updated, false);
|
||||
Utils.showOkMessage(mContext, R.string.profile_banner_image_updated, false);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new ProfileUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(),
|
||||
Utils.showErrorMessage(mContext, R.string.action_updating_profile_banner_image, result.getException(),
|
||||
true);
|
||||
}
|
||||
}
|
||||
@ -669,11 +657,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
|
||||
super.onPostExecute(result);
|
||||
if (result.hasData()) {
|
||||
showOkMessage(mContext, R.string.profile_image_updated, false);
|
||||
Utils.showOkMessage(mContext, R.string.profile_image_updated, false);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new ProfileUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_updating_profile_image, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_updating_profile_image, result.getException(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,9 +709,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.accepted_users_follow_request,
|
||||
manager.getDisplayName(user, nameFirst, true));
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_accepting_follow_request,
|
||||
Utils.showErrorMessage(mContext, R.string.action_accepting_follow_request,
|
||||
result.getException(), false);
|
||||
}
|
||||
final Intent intent = new Intent(BROADCAST_FRIENDSHIP_ACCEPTED);
|
||||
@ -780,9 +769,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
message = res.getQuantityString(R.plurals.added_N_users_to_list, users.length, users.length,
|
||||
result.getData().name);
|
||||
}
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_adding_member, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_adding_member, result.getException(), true);
|
||||
}
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_MEMBERS_ADDED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
@ -840,7 +829,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
try {
|
||||
final User user = twitter.createBlock(user_id);
|
||||
Utils.setLastSeen(mContext, user.getId(), -1);
|
||||
for (final Uri uri : STATUSES_URIS) {
|
||||
for (final Uri uri : TwidereDataStore.STATUSES_URIS) {
|
||||
final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id),
|
||||
Expression.equals(Statuses.USER_ID, user_id));
|
||||
mResolver.delete(uri, where.getSQL(), null);
|
||||
@ -864,11 +853,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.blocked_user,
|
||||
manager.getDisplayName(result.getData(), nameFirst, true));
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_blocking, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_blocking, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -918,6 +908,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPreExecute();
|
||||
mCreatingFavoriteIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@ -940,10 +931,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
//end
|
||||
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FavoriteCreatedEvent(status));
|
||||
showOkMessage(mContext, R.string.status_favorited, false);
|
||||
Utils.showOkMessage(mContext, R.string.status_favorited, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_favoriting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_favoriting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -998,11 +990,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
message = mContext.getString(R.string.followed_user,
|
||||
manager.getDisplayName(user, nameFirst, true));
|
||||
}
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_following, result.getException(), false);
|
||||
Utils.showErrorMessage(mContext, R.string.action_following, result.getException(), false);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1021,8 +1014,8 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
}
|
||||
|
||||
private void deleteCaches(final List<Long> list) {
|
||||
for (final Uri uri : STATUSES_URIS) {
|
||||
bulkDelete(mResolver, uri, Statuses.USER_ID, list, Statuses.ACCOUNT_ID + " = " + account_id, false);
|
||||
for (final Uri uri : TwidereDataStore.STATUSES_URIS) {
|
||||
ContentResolverUtils.bulkDelete(mResolver, uri, Statuses.USER_ID, list, Statuses.ACCOUNT_ID + " = " + account_id, false);
|
||||
}
|
||||
// I bet you don't want to see these users in your auto complete list.
|
||||
//TODO insert to blocked users data
|
||||
@ -1054,9 +1047,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
@Override
|
||||
protected void onPostExecute(final ListResponse<Long> result) {
|
||||
if (result.list != null) {
|
||||
showInfoMessage(mContext, R.string.users_blocked, false);
|
||||
Utils.showInfoMessage(mContext, R.string.users_blocked, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_blocking, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_blocking, result.getException(), true);
|
||||
}
|
||||
final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED);
|
||||
intent.putExtra(EXTRA_USER_ID, user_ids);
|
||||
@ -1102,11 +1095,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.muted_user,
|
||||
manager.getDisplayName(result.getData(), nameFirst, true));
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_muting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_muting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1139,9 +1133,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final SingleResponse<SavedSearch> result) {
|
||||
if (result.hasData()) {
|
||||
final String message = mContext.getString(R.string.search_name_saved, result.getData().getQuery());
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_saving_search, result.getException(), false);
|
||||
Utils.showErrorMessage(mContext, R.string.action_saving_search, result.getException(), false);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1178,12 +1172,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean succeed = result.hasData();
|
||||
if (succeed) {
|
||||
final String message = mContext.getString(R.string.subscribed_to_list, result.getData().name);
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_SUBSCRIBED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_subscribing_to_list, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_subscribing_to_list, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1226,12 +1220,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
if (result.hasData()) {
|
||||
final UserList userList = result.getData();
|
||||
final String message = mContext.getString(R.string.created_list, userList.getName());
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_CREATED);
|
||||
intent.putExtra(EXTRA_USER_LIST, new ParcelableUserList(userList, account_id));
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_creating_list, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_creating_list, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1285,13 +1279,13 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
message = res.getQuantityString(R.plurals.deleted_N_users_from_list, users.length, users.length,
|
||||
result.getData().name);
|
||||
}
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_MEMBERS_DELETED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
intent.putExtra(EXTRA_USERS, users);
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1339,9 +1333,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.denied_users_follow_request,
|
||||
manager.getDisplayName(user, nameFirst, true));
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_denying_follow_request, result.getException(), false);
|
||||
Utils.showErrorMessage(mContext, R.string.action_denying_follow_request, result.getException(), false);
|
||||
}
|
||||
final Intent intent = new Intent(BROADCAST_FRIENDSHIP_DENIED);
|
||||
intent.putExtra(EXTRA_USER_ID, mUserId);
|
||||
@ -1384,11 +1378,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.unblocked_user,
|
||||
manager.getDisplayName(result.getData(), nameFirst, true));
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_unblocking, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_unblocking, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1442,9 +1437,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPostExecute(result);
|
||||
if (result == null) return;
|
||||
if (result.hasData() || isMessageNotFound(result.getException())) {
|
||||
showInfoMessage(mContext, R.string.direct_message_deleted, false);
|
||||
Utils.showInfoMessage(mContext, R.string.direct_message_deleted, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1500,9 +1495,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPostExecute(result);
|
||||
if (result == null) return;
|
||||
if (result.hasData() || isMessageNotFound(result.getException())) {
|
||||
showInfoMessage(mContext, R.string.direct_message_deleted, false);
|
||||
Utils.showInfoMessage(mContext, R.string.direct_message_deleted, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1554,6 +1549,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPreExecute();
|
||||
mDestroyingFavoriteIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@ -1576,10 +1572,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
//end
|
||||
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FavoriteDestroyedEvent(status));
|
||||
showInfoMessage(mContext, R.string.status_unfavorited, false);
|
||||
Utils.showInfoMessage(mContext, R.string.status_unfavorited, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_unfavoriting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_unfavoriting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1634,11 +1631,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.unfollowed_user,
|
||||
manager.getDisplayName(result.getData(), nameFirst, true));
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_unfollowing, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_unfollowing, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1678,11 +1676,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean nameFirst = mPreferences.getBoolean(KEY_NAME_FIRST);
|
||||
final String message = mContext.getString(R.string.unmuted_user,
|
||||
manager.getDisplayName(result.getData(), nameFirst, true));
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Bus bus = application.getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_unmuting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_unmuting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1715,9 +1714,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final SingleResponse<SavedSearch> result) {
|
||||
if (result.hasData()) {
|
||||
final String message = mContext.getString(R.string.search_name_deleted, result.getData().getQuery());
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting_search, result.getException(), false);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting_search, result.getException(), false);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1763,6 +1762,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPreExecute();
|
||||
mDestroyingStatusIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@ -1772,14 +1772,15 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
if (result.hasData()) {
|
||||
final ParcelableStatus status = result.getData();
|
||||
if (status.retweet_id > 0) {
|
||||
showInfoMessage(mContext, R.string.retweet_cancelled, false);
|
||||
Utils.showInfoMessage(mContext, R.string.retweet_cancelled, false);
|
||||
} else {
|
||||
showInfoMessage(mContext, R.string.status_deleted, false);
|
||||
Utils.showInfoMessage(mContext, R.string.status_deleted, false);
|
||||
}
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusDestroyedEvent(status));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1818,12 +1819,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean succeed = result.hasData();
|
||||
if (succeed) {
|
||||
final String message = mContext.getString(R.string.unsubscribed_from_list, result.getData().name);
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_UNSUBSCRIBED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_unsubscribing_from_list, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_unsubscribing_from_list, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1864,12 +1865,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final boolean succeed = result.hasData();
|
||||
if (succeed) {
|
||||
final String message = mContext.getString(R.string.deleted_list, result.getData().name);
|
||||
showInfoMessage(mContext, message, false);
|
||||
Utils.showInfoMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_DELETED);
|
||||
intent.putExtra(EXTRA_USER_LIST, result.getData());
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_deleting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -1952,7 +1953,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
for (int i = 0, j = messages.size(); i < j; i++) {
|
||||
final DirectMessage message = messages.get(i);
|
||||
valuesArray[i] = createDirectMessage(message, accountId, isOutgoing);
|
||||
valuesArray[i] = ContentValuesCreator.createDirectMessage(message, accountId, isOutgoing);
|
||||
}
|
||||
|
||||
// Delete all rows conflicting before new data inserted.
|
||||
@ -1964,7 +1965,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
// Insert previously fetched items.
|
||||
final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
|
||||
bulkInsert(mResolver, insertUri, valuesArray);
|
||||
ContentResolverUtils.bulkInsert(mResolver, insertUri, valuesArray);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1973,6 +1974,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
final Bus bus = TwidereApplication.getInstance(getContext()).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), true, null));
|
||||
}
|
||||
|
||||
@ -1980,6 +1982,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final List<MessageListResponse> result) {
|
||||
super.onPostExecute(result);
|
||||
final Bus bus = TwidereApplication.getInstance(getContext()).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new GetMessagesTaskEvent(getDatabaseUri(), false, getException(result)));
|
||||
}
|
||||
|
||||
@ -2178,14 +2181,14 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
return;
|
||||
}
|
||||
final Uri uri = getDatabaseUri();
|
||||
final boolean noItemsBefore = getStatusCountInDatabase(mContext, uri, accountId) <= 0;
|
||||
final boolean noItemsBefore = Utils.getStatusCountInDatabase(mContext, uri, accountId) <= 0;
|
||||
final ContentValues[] values = new ContentValues[statuses.size()];
|
||||
final long[] statusIds = new long[statuses.size()];
|
||||
long minId = -1;
|
||||
int minIdx = -1;
|
||||
for (int i = 0, j = statuses.size(); i < j; i++) {
|
||||
final org.mariotaku.twidere.api.twitter.model.Status status = statuses.get(i);
|
||||
values[i] = createStatus(status, accountId);
|
||||
values[i] = ContentValuesCreator.createStatus(status, accountId);
|
||||
final long id = status.getId();
|
||||
if (minId == -1 || id < minId) {
|
||||
minId = id;
|
||||
@ -2220,7 +2223,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
}
|
||||
// Insert previously fetched items.
|
||||
final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
|
||||
bulkInsert(mResolver, insertUri, values);
|
||||
ContentResolverUtils.bulkInsert(mResolver, insertUri, values);
|
||||
|
||||
}
|
||||
|
||||
@ -2288,6 +2291,151 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
|
||||
}
|
||||
|
||||
abstract class GetActivitiesTask extends ManagedAsyncTask<Object, TwitterListResponse<Activity>, List<ActivityListResponse>> {
|
||||
|
||||
private final long[] mAccountIds, mMaxIds, mSinceIds;
|
||||
|
||||
public GetActivitiesTask(final long[] account_ids, final long[] max_ids, final long[] since_ids, final String tag) {
|
||||
super(mContext, mAsyncTaskManager, tag);
|
||||
mAccountIds = account_ids;
|
||||
mMaxIds = max_ids;
|
||||
mSinceIds = since_ids;
|
||||
}
|
||||
|
||||
public abstract ResponseList<Activity> getActivities(Twitter twitter, Paging paging)
|
||||
throws TwitterException;
|
||||
|
||||
@NonNull
|
||||
protected abstract Uri getDatabaseUri();
|
||||
|
||||
final boolean isMaxIdsValid() {
|
||||
return mMaxIds != null && mMaxIds.length == mAccountIds.length;
|
||||
}
|
||||
|
||||
final boolean isSinceIdsValid() {
|
||||
return mSinceIds != null && mSinceIds.length == mAccountIds.length;
|
||||
}
|
||||
|
||||
private void storeStatus(long accountId, List<Activity> statuses, Pair<Long, Long> positions, boolean truncated, boolean notify) {
|
||||
if (statuses == null || statuses.isEmpty() || accountId <= 0) {
|
||||
return;
|
||||
}
|
||||
// final Uri uri = getDatabaseUri();
|
||||
// final boolean noItemsBefore = Utils.getStatusCountInDatabase(mContext, uri, accountId) <= 0;
|
||||
// final ContentValues[] values = new ContentValues[statuses.size()];
|
||||
// final long[] statusIds = new long[statuses.size()];
|
||||
// long minId = -1;
|
||||
// int minIdx = -1;
|
||||
// for (int i = 0, j = statuses.size(); i < j; i++) {
|
||||
// final Activity status = statuses.get(i);
|
||||
// values[i] = ContentValuesCreator.createActivity(status, accountId);
|
||||
// final long id = status.getId();
|
||||
// if (minId == -1 || id < minId) {
|
||||
// minId = id;
|
||||
// minIdx = i;
|
||||
// }
|
||||
// statusIds[i] = id;
|
||||
// }
|
||||
// // Delete all rows conflicting before new data inserted.
|
||||
// final Expression accountWhere = Expression.equals(Activities.ACCOUNT_ID, accountId);
|
||||
// final Expression statusWhere = Expression.in(new Column(Activities.STATUS_ID), new RawItemArray(statusIds));
|
||||
// final String countWhere = Expression.and(accountWhere, statusWhere).getSQL();
|
||||
// final String[] projection = {SQLFunctions.COUNT()};
|
||||
// final int rowsDeleted;
|
||||
// final Cursor countCur = mResolver.query(uri, projection, countWhere, null, null);
|
||||
// if (countCur.moveToFirst()) {
|
||||
// rowsDeleted = countCur.getInt(0);
|
||||
// } else {
|
||||
// rowsDeleted = 0;
|
||||
// }
|
||||
// countCur.close();
|
||||
// //spice
|
||||
// SpiceProfilingUtil.profile(mContext, accountId, accountId + ",Refresh," + TwidereArrayUtils.toString(statusIds, ',', true));
|
||||
// //end
|
||||
//
|
||||
// // Insert a gap.
|
||||
// final boolean deletedOldGap = rowsDeleted > 0 && ArrayUtils.contains(statusIds, positions);
|
||||
// final boolean noRowsDeleted = rowsDeleted == 0;
|
||||
// final boolean insertGap = minId > 0 && (noRowsDeleted || deletedOldGap) && !truncated
|
||||
// && !noItemsBefore && statuses.size() > 1;
|
||||
// if (insertGap && minIdx != -1) {
|
||||
// values[minIdx].put(Statuses.IS_GAP, true);
|
||||
// }
|
||||
// // Insert previously fetched items.
|
||||
// final Uri insertUri = UriUtils.appendQueryParameters(uri, QUERY_PARAM_NOTIFY, notify);
|
||||
// ContentResolverUtils.bulkInsert(mResolver, insertUri, values);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@Override
|
||||
protected final void onProgressUpdate(TwitterListResponse<Activity>... values) {
|
||||
// AsyncTaskUtils.executeTask(new CacheUsersStatusesTask(mContext), values);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<ActivityListResponse> result) {
|
||||
super.onPostExecute(result);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), false, getException(result)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new GetStatusesTaskEvent(getDatabaseUri(), true, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ActivityListResponse> doInBackground(final Object... params) {
|
||||
final List<ActivityListResponse> result = new ArrayList<>();
|
||||
if (mAccountIds == null) return result;
|
||||
int idx = 0;
|
||||
final int loadItemLimit = mPreferences.getInt(KEY_LOAD_ITEM_LIMIT, DEFAULT_LOAD_ITEM_LIMIT);
|
||||
for (final long accountId : mAccountIds) {
|
||||
final Twitter twitter = TwitterAPIFactory.getTwitterInstance(mContext, accountId, true);
|
||||
if (twitter == null) continue;
|
||||
try {
|
||||
final Paging paging = new Paging();
|
||||
paging.count(loadItemLimit);
|
||||
final long maxId, sinceId;
|
||||
if (isMaxIdsValid() && mMaxIds[idx] > 0) {
|
||||
maxId = mMaxIds[idx];
|
||||
paging.maxId(maxId);
|
||||
} else {
|
||||
maxId = -1;
|
||||
}
|
||||
if (isSinceIdsValid() && mSinceIds[idx] > 0) {
|
||||
sinceId = mSinceIds[idx];
|
||||
paging.sinceId(sinceId - 1);
|
||||
} else {
|
||||
sinceId = -1;
|
||||
}
|
||||
final List<Activity> activities = new ArrayList<>();
|
||||
final boolean truncated = Utils.truncateActivities(getActivities(twitter, paging), activities, sinceId);
|
||||
final Pair<Long, Long> positions;
|
||||
if (activities.isEmpty()) {
|
||||
positions = new Pair<>(-1L, -1L);
|
||||
} else {
|
||||
final Activity minActivity = Collections.min(activities);
|
||||
positions = new Pair<>(minActivity.getMinPosition(), minActivity.getMaxPosition());
|
||||
}
|
||||
storeStatus(accountId, activities, positions, truncated, true);
|
||||
publishProgress(new ActivityListResponse(accountId, activities));
|
||||
} catch (final TwitterException e) {
|
||||
Log.w(LOGTAG, e);
|
||||
result.add(new ActivityListResponse(accountId, e));
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class GetTrendsTask extends ManagedAsyncTask<Object, Object, ListResponse<Trends>> {
|
||||
|
||||
private final long account_id;
|
||||
@ -2370,12 +2518,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final ListResponse<Long> result) {
|
||||
if (result != null) {
|
||||
final String user_id_where = ListUtils.toString(result.list, ',', false);
|
||||
for (final Uri uri : STATUSES_URIS) {
|
||||
for (final Uri uri : TwidereDataStore.STATUSES_URIS) {
|
||||
final Expression where = Expression.and(Expression.equals(Statuses.ACCOUNT_ID, account_id),
|
||||
new Expression(String.format(Locale.ROOT, "%s IN (%s)", Statuses.USER_ID, user_id_where)));
|
||||
mResolver.delete(uri, where.getSQL(), null);
|
||||
}
|
||||
showInfoMessage(mContext, R.string.reported_users_for_spam, false);
|
||||
Utils.showInfoMessage(mContext, R.string.reported_users_for_spam, false);
|
||||
final Intent intent = new Intent(BROADCAST_MULTI_BLOCKSTATE_CHANGED);
|
||||
intent.putExtra(EXTRA_USER_IDS, user_ids);
|
||||
intent.putExtra(EXTRA_ACCOUNT_ID, account_id);
|
||||
@ -2414,16 +2562,16 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
@Override
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUser> result) {
|
||||
if (result.hasData()) {
|
||||
for (final Uri uri : STATUSES_URIS) {
|
||||
for (final Uri uri : TwidereDataStore.STATUSES_URIS) {
|
||||
final String where = Statuses.ACCOUNT_ID + " = " + mAccountId + " AND " + Statuses.USER_ID + " = "
|
||||
+ user_id;
|
||||
mResolver.delete(uri, where, null);
|
||||
}
|
||||
showInfoMessage(mContext, R.string.reported_user_for_spam, false);
|
||||
Utils.showInfoMessage(mContext, R.string.reported_user_for_spam, false);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
bus.post(new FriendshipUserUpdatedEvent(result.getData()));
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_reporting_for_spam, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_reporting_for_spam, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -2463,6 +2611,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
super.onPreExecute();
|
||||
mCreatingRetweetIds.put(account_id, status_id);
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusListChangedEvent());
|
||||
}
|
||||
|
||||
@ -2477,7 +2626,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
Expression.equals(Statuses.STATUS_ID, status_id),
|
||||
Expression.equals(Statuses.RETWEET_ID, status_id)
|
||||
);
|
||||
for (final Uri uri : STATUSES_URIS) {
|
||||
for (final Uri uri : TwidereDataStore.STATUSES_URIS) {
|
||||
mResolver.update(uri, values, where.getSQL(), null);
|
||||
}
|
||||
//spice
|
||||
@ -2507,10 +2656,11 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
}
|
||||
//end
|
||||
final Bus bus = TwidereApplication.getInstance(mContext).getMessageBus();
|
||||
assert bus != null;
|
||||
bus.post(new StatusRetweetedEvent(status));
|
||||
showOkMessage(mContext, R.string.status_retweeted, false);
|
||||
Utils.showOkMessage(mContext, R.string.status_retweeted, false);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_retweeting, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_retweeting, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
@ -2544,7 +2694,7 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
final ArrayList<String> hashtags = new ArrayList<>();
|
||||
final ArrayList<ContentValues> hashtagValues = new ArrayList<>();
|
||||
if (messages != null && messages.size() > 0) {
|
||||
final ContentValues[] valuesArray = createTrends(messages);
|
||||
final ContentValues[] valuesArray = ContentValuesCreator.createTrends(messages);
|
||||
for (final ContentValues values : valuesArray) {
|
||||
final String hashtag = values.getAsString(CachedTrends.NAME).replaceFirst("#", "");
|
||||
if (hashtags.contains(hashtag)) {
|
||||
@ -2556,9 +2706,9 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
hashtagValues.add(hashtagValue);
|
||||
}
|
||||
mResolver.delete(uri, null, null);
|
||||
bulkInsert(mResolver, uri, valuesArray);
|
||||
bulkDelete(mResolver, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, hashtags, null, true);
|
||||
bulkInsert(mResolver, CachedHashtags.CONTENT_URI,
|
||||
ContentResolverUtils.bulkInsert(mResolver, uri, valuesArray);
|
||||
ContentResolverUtils.bulkDelete(mResolver, CachedHashtags.CONTENT_URI, CachedHashtags.NAME, hashtags, null, true);
|
||||
ContentResolverUtils.bulkInsert(mResolver, CachedHashtags.CONTENT_URI,
|
||||
hashtagValues.toArray(new ContentValues[hashtagValues.size()]));
|
||||
}
|
||||
return SingleResponse.getInstance(true);
|
||||
@ -2609,12 +2759,12 @@ public class AsyncTwitterWrapper extends TwitterWrapper {
|
||||
protected void onPostExecute(final SingleResponse<ParcelableUserList> result) {
|
||||
if (result.hasData() && result.getData().id > 0) {
|
||||
final String message = mContext.getString(R.string.updated_list_details, result.getData().name);
|
||||
showOkMessage(mContext, message, false);
|
||||
Utils.showOkMessage(mContext, message, false);
|
||||
final Intent intent = new Intent(BROADCAST_USER_LIST_DETAILS_UPDATED);
|
||||
intent.putExtra(EXTRA_LIST_ID, listId);
|
||||
mContext.sendBroadcast(intent);
|
||||
} else {
|
||||
showErrorMessage(mContext, R.string.action_updating_details, result.getException(), true);
|
||||
Utils.showErrorMessage(mContext, R.string.action_updating_details, result.getException(), true);
|
||||
}
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
|
@ -19,17 +19,17 @@
|
||||
|
||||
package org.mariotaku.twidere.util;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.Join;
|
||||
import org.mariotaku.querybuilder.Join.Operation;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.SQLQueryBuilder;
|
||||
import org.mariotaku.querybuilder.Selectable;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.Tables;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.Join;
|
||||
import org.mariotaku.sqliteqb.library.Join.Operation;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
|
||||
import org.mariotaku.sqliteqb.library.Selectable;
|
||||
import org.mariotaku.sqliteqb.library.Table;
|
||||
import org.mariotaku.sqliteqb.library.Tables;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedRelationships;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedUsers;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.DirectMessages;
|
||||
|
@ -29,6 +29,7 @@ import org.mariotaku.restfu.http.mime.FileTypedData;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.api.twitter.Twitter;
|
||||
import org.mariotaku.twidere.api.twitter.TwitterException;
|
||||
import org.mariotaku.twidere.api.twitter.model.Activity;
|
||||
import org.mariotaku.twidere.api.twitter.model.DirectMessage;
|
||||
import org.mariotaku.twidere.api.twitter.model.Paging;
|
||||
import org.mariotaku.twidere.api.twitter.model.ResponseList;
|
||||
@ -260,6 +261,31 @@ public class TwitterWrapper implements Constants {
|
||||
|
||||
}
|
||||
|
||||
public static final class ActivityListResponse extends TwitterListResponse<Activity> {
|
||||
|
||||
public final boolean truncated;
|
||||
|
||||
public ActivityListResponse(final long accountId, final Exception exception) {
|
||||
this(accountId, -1, -1, null, false, exception);
|
||||
}
|
||||
|
||||
public ActivityListResponse(final long accountId, final List<Activity> list) {
|
||||
this(accountId, -1, -1, list, false, null);
|
||||
}
|
||||
|
||||
public ActivityListResponse(final long accountId, final long maxId, final long sinceId,
|
||||
final List<Activity> list, final boolean truncated) {
|
||||
this(accountId, maxId, sinceId, list, truncated, null);
|
||||
}
|
||||
|
||||
ActivityListResponse(final long accountId, final long maxId, final long sinceId, final List<Activity> list,
|
||||
final boolean truncated, final Exception exception) {
|
||||
super(accountId, maxId, sinceId, list, exception);
|
||||
this.truncated = truncated;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TwitterListResponse<Data> extends ListResponse<Data> {
|
||||
|
||||
public final long accountId, maxId, sinceId;
|
||||
|
@ -120,18 +120,18 @@ import org.apache.http.protocol.HTTP;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mariotaku.querybuilder.AllColumns;
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.OrderBy;
|
||||
import org.mariotaku.querybuilder.RawItemArray;
|
||||
import org.mariotaku.querybuilder.SQLFunctions;
|
||||
import org.mariotaku.querybuilder.SQLQueryBuilder;
|
||||
import org.mariotaku.querybuilder.Selectable;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.Tables;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.sqliteqb.library.AllColumns;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.OrderBy;
|
||||
import org.mariotaku.sqliteqb.library.RawItemArray;
|
||||
import org.mariotaku.sqliteqb.library.SQLFunctions;
|
||||
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
|
||||
import org.mariotaku.sqliteqb.library.Selectable;
|
||||
import org.mariotaku.sqliteqb.library.Table;
|
||||
import org.mariotaku.sqliteqb.library.Tables;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
|
||||
import org.mariotaku.restfu.RestAPIFactory;
|
||||
import org.mariotaku.restfu.RestClient;
|
||||
import org.mariotaku.restfu.http.Authorization;
|
||||
@ -200,6 +200,7 @@ import org.mariotaku.twidere.model.ParcelableUser;
|
||||
import org.mariotaku.twidere.model.ParcelableUserList;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CacheFiles;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedImages;
|
||||
@ -589,6 +590,58 @@ public final class Utils implements Constants {
|
||||
return filterExpression;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Expression buildActivityFilterWhereClause(@NonNull final String table, final Expression extraSelection) {
|
||||
final SQLSelectQuery filteredUsersQuery = SQLQueryBuilder
|
||||
.select(new Column(new Table(Filters.Users.TABLE_NAME), Filters.Users.USER_ID))
|
||||
.from(new Tables(Filters.Users.TABLE_NAME))
|
||||
.build();
|
||||
final Expression filteredUsersWhere = Expression.or(
|
||||
Expression.in(new Column(new Table(table), Activities.STATUS_USER_ID), filteredUsersQuery),
|
||||
Expression.in(new Column(new Table(table), Activities.STATUS_RETWEETED_BY_USER_ID), filteredUsersQuery),
|
||||
Expression.in(new Column(new Table(table), Activities.STATUS_QUOTED_BY_USER_ID), filteredUsersQuery)
|
||||
);
|
||||
final SQLSelectQuery.Builder filteredIdsQueryBuilder = SQLQueryBuilder
|
||||
.select(true, new Column(new Table(table), Activities._ID))
|
||||
.from(new Tables(table))
|
||||
.where(filteredUsersWhere)
|
||||
.union()
|
||||
.select(true, new Columns(new Column(new Table(table), Activities._ID)))
|
||||
.from(new Tables(table, Filters.Sources.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_SOURCE),
|
||||
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'"),
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_QUOTE_SOURCE),
|
||||
"'%>'||" + Filters.Sources.TABLE_NAME + "." + Filters.Sources.VALUE + "||'</a>%'")
|
||||
))
|
||||
.union()
|
||||
.select(true, new Columns(new Column(new Table(table), Activities._ID)))
|
||||
.from(new Tables(table, Filters.Keywords.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_TEXT_PLAIN),
|
||||
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'"),
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_QUOTE_TEXT_PLAIN),
|
||||
"'%'||" + Filters.Keywords.TABLE_NAME + "." + Filters.Keywords.VALUE + "||'%'")
|
||||
))
|
||||
.union()
|
||||
.select(true, new Columns(new Column(new Table(table), Activities._ID)))
|
||||
.from(new Tables(table, Filters.Links.TABLE_NAME))
|
||||
.where(Expression.or(
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_TEXT_HTML),
|
||||
"'%>%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%</a>%'"),
|
||||
Expression.likeRaw(new Column(new Table(table), Activities.STATUS_QUOTE_TEXT_HTML),
|
||||
"'%>%'||" + Filters.Links.TABLE_NAME + "." + Filters.Links.VALUE + "||'%</a>%'")
|
||||
));
|
||||
final Expression filterExpression = Expression.or(
|
||||
Expression.notIn(new Column(new Table(table), Activities._ID), filteredIdsQueryBuilder.build()),
|
||||
Expression.equals(new Column(new Table(table), Activities.STATUS_IS_GAP), 1)
|
||||
);
|
||||
if (extraSelection != null) {
|
||||
return Expression.and(filterExpression, extraSelection);
|
||||
}
|
||||
return filterExpression;
|
||||
}
|
||||
|
||||
public static int calculateInSampleSize(final int width, final int height, final int preferredWidth,
|
||||
final int preferredHeight) {
|
||||
if (preferredHeight > height && preferredWidth > width) return 1;
|
||||
|
@ -24,15 +24,15 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Constraint;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.NewColumn;
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.Tables;
|
||||
import org.mariotaku.querybuilder.query.SQLInsertQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLSelectQuery;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Constraint;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.NewColumn;
|
||||
import org.mariotaku.sqliteqb.library.OnConflict;
|
||||
import org.mariotaku.sqliteqb.library.Tables;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLInsertQuery;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLSelectQuery;
|
||||
import org.mariotaku.twidere.util.TwidereArrayUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -42,11 +42,11 @@ import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mariotaku.querybuilder.SQLQueryBuilder.alterTable;
|
||||
import static org.mariotaku.querybuilder.SQLQueryBuilder.createTable;
|
||||
import static org.mariotaku.querybuilder.SQLQueryBuilder.dropTable;
|
||||
import static org.mariotaku.querybuilder.SQLQueryBuilder.insertInto;
|
||||
import static org.mariotaku.querybuilder.SQLQueryBuilder.select;
|
||||
import static org.mariotaku.sqliteqb.library.SQLQueryBuilder.alterTable;
|
||||
import static org.mariotaku.sqliteqb.library.SQLQueryBuilder.createTable;
|
||||
import static org.mariotaku.sqliteqb.library.SQLQueryBuilder.dropTable;
|
||||
import static org.mariotaku.sqliteqb.library.SQLQueryBuilder.insertInto;
|
||||
import static org.mariotaku.sqliteqb.library.SQLQueryBuilder.select;
|
||||
|
||||
public final class DatabaseUpgradeHelper {
|
||||
|
||||
|
@ -26,21 +26,21 @@ import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.os.Build;
|
||||
|
||||
import org.mariotaku.querybuilder.Columns;
|
||||
import org.mariotaku.querybuilder.Columns.Column;
|
||||
import org.mariotaku.querybuilder.Constraint;
|
||||
import org.mariotaku.querybuilder.Expression;
|
||||
import org.mariotaku.querybuilder.NewColumn;
|
||||
import org.mariotaku.querybuilder.OnConflict;
|
||||
import org.mariotaku.querybuilder.SQLQuery;
|
||||
import org.mariotaku.querybuilder.SQLQueryBuilder;
|
||||
import org.mariotaku.querybuilder.SetValue;
|
||||
import org.mariotaku.querybuilder.Table;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateIndexQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateTableQuery;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateTriggerQuery.Event;
|
||||
import org.mariotaku.querybuilder.query.SQLCreateTriggerQuery.Type;
|
||||
import org.mariotaku.querybuilder.query.SQLDeleteQuery;
|
||||
import org.mariotaku.sqliteqb.library.Columns;
|
||||
import org.mariotaku.sqliteqb.library.Columns.Column;
|
||||
import org.mariotaku.sqliteqb.library.Constraint;
|
||||
import org.mariotaku.sqliteqb.library.Expression;
|
||||
import org.mariotaku.sqliteqb.library.NewColumn;
|
||||
import org.mariotaku.sqliteqb.library.OnConflict;
|
||||
import org.mariotaku.sqliteqb.library.SQLQuery;
|
||||
import org.mariotaku.sqliteqb.library.SQLQueryBuilder;
|
||||
import org.mariotaku.sqliteqb.library.SetValue;
|
||||
import org.mariotaku.sqliteqb.library.Table;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLCreateIndexQuery;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLCreateTableQuery;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLCreateTriggerQuery.Event;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLCreateTriggerQuery.Type;
|
||||
import org.mariotaku.sqliteqb.library.query.SQLDeleteQuery;
|
||||
import org.mariotaku.twidere.Constants;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.Accounts;
|
||||
import org.mariotaku.twidere.provider.TwidereDataStore.CachedHashtags;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package org.mariotaku.twidere.view.holder;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.CardView;
|
||||
@ -24,7 +23,6 @@ import org.mariotaku.twidere.app.TwidereApplication;
|
||||
import org.mariotaku.twidere.model.ParcelableLocation;
|
||||
import org.mariotaku.twidere.model.ParcelableMedia;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus;
|
||||
import org.mariotaku.twidere.model.ParcelableStatus.CursorIndices;
|
||||
import org.mariotaku.twidere.util.AsyncTwitterWrapper;
|
||||
import org.mariotaku.twidere.util.MediaLoaderWrapper;
|
||||
import org.mariotaku.twidere.util.MediaLoadingHandler;
|
||||
@ -330,217 +328,6 @@ public class StatusViewHolder extends ViewHolder implements Constants, OnClickLi
|
||||
quotedNameView.updateText();
|
||||
}
|
||||
|
||||
public void displayStatus(@NonNull Cursor cursor, @NonNull CursorIndices indices,
|
||||
final boolean displayInReplyTo) {
|
||||
final MediaLoaderWrapper loader = adapter.getMediaLoader();
|
||||
final AsyncTwitterWrapper twitter = adapter.getTwitterWrapper();
|
||||
final TwidereLinkify linkify = adapter.getTwidereLinkify();
|
||||
final UserColorNameManager manager = adapter.getUserColorNameManager();
|
||||
final Context context = adapter.getContext();
|
||||
final boolean nameFirst = adapter.isNameFirst();
|
||||
|
||||
final boolean is_quote = cursor.getShort(indices.is_quote) == 1;
|
||||
|
||||
final long reply_count = cursor.getLong(is_quote ? indices.quote_reply_count : indices.reply_count);
|
||||
final long retweet_count;
|
||||
final long favorite_count;
|
||||
|
||||
final long account_id = cursor.getLong(indices.account_id);
|
||||
final long user_id = cursor.getLong(indices.user_id);
|
||||
final long status_id = cursor.getLong(indices.status_id);
|
||||
final long retweet_id = cursor.getLong(indices.retweet_id);
|
||||
final long my_retweet_id = cursor.getLong(indices.my_retweet_id);
|
||||
final long in_reply_to_status_id = cursor.getLong(indices.in_reply_to_status_id);
|
||||
final long in_reply_to_user_id = cursor.getLong(indices.in_reply_to_user_id);
|
||||
final long retweeted_by_id = cursor.getLong(indices.retweeted_by_user_id);
|
||||
|
||||
final String user_name = cursor.getString(indices.user_name);
|
||||
final String user_screen_name = cursor.getString(indices.user_screen_name);
|
||||
final String card_name = cursor.getString(indices.card_name);
|
||||
final String place_full_name = cursor.getString(indices.place_full_name);
|
||||
|
||||
final boolean sensitive = cursor.getShort(indices.is_possibly_sensitive) == 1;
|
||||
|
||||
final ParcelableMedia[] media = ParcelableMedia.fromSerializedJson(cursor.getString(indices.media));
|
||||
final ParcelableLocation location = ParcelableLocation.fromString(cursor.getString(indices.location));
|
||||
|
||||
if (retweet_id > 0) {
|
||||
final String retweeted_by_name = cursor.getString(indices.retweeted_by_user_name);
|
||||
final String retweeted_by_screen_name = cursor.getString(indices.retweeted_by_user_screen_name);
|
||||
final String retweetedBy = manager.getDisplayName(retweeted_by_id, retweeted_by_name,
|
||||
retweeted_by_screen_name, nameFirst, false);
|
||||
replyRetweetView.setText(context.getString(R.string.name_retweeted, retweetedBy));
|
||||
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_retweet);
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
} else if (in_reply_to_status_id > 0 && in_reply_to_user_id > 0 && displayInReplyTo) {
|
||||
final String in_reply_to_name = cursor.getString(indices.in_reply_to_user_name);
|
||||
final String in_reply_to_screen_name = cursor.getString(indices.in_reply_to_user_screen_name);
|
||||
final String inReplyTo = manager.getDisplayName(in_reply_to_user_id, in_reply_to_name,
|
||||
in_reply_to_screen_name, nameFirst, false);
|
||||
replyRetweetView.setText(context.getString(R.string.in_reply_to_name, inReplyTo));
|
||||
replyRetweetIcon.setImageResource(R.drawable.ic_activity_action_reply);
|
||||
replyRetweetView.setVisibility(View.VISIBLE);
|
||||
replyRetweetIcon.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
replyRetweetView.setVisibility(View.GONE);
|
||||
replyRetweetIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final int typeIconRes;
|
||||
|
||||
if (is_quote) {
|
||||
quotedNameView.setName(manager.getUserNickname(user_id, user_name, false));
|
||||
quotedNameView.setScreenName("@" + user_screen_name);
|
||||
timeView.setTime(cursor.getLong(indices.quote_timestamp));
|
||||
nameView.setName(manager.getUserNickname(cursor.getLong(indices.quoted_by_user_id),
|
||||
cursor.getString(indices.quoted_by_user_name), false));
|
||||
nameView.setScreenName("@" + cursor.getString(indices.quoted_by_user_screen_name));
|
||||
|
||||
final String quote_text_unescaped = cursor.getString(indices.quote_text_unescaped);
|
||||
final int idx = quote_text_unescaped.lastIndexOf(" twitter.com");
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
quoteTextView.setText(idx > 0 ? quote_text_unescaped.substring(0, idx) : quote_text_unescaped);
|
||||
} else {
|
||||
final Spanned text = Html.fromHtml(cursor.getString(indices.quote_text_html));
|
||||
quoteTextView.setText(idx > 0 ? text.subSequence(0, idx) : text);
|
||||
linkify.applyAllLinks(quoteTextView, account_id, getLayoutPosition(),
|
||||
cursor.getShort(indices.is_possibly_sensitive) == 1,
|
||||
adapter.getLinkHighlightingStyle());
|
||||
quoteTextView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
quotedNameView.setVisibility(View.VISIBLE);
|
||||
quoteTextView.setVisibility(View.VISIBLE);
|
||||
quoteIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
quoteIndicator.setColor(manager.getUserColor(user_id, false));
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
loader.displayProfileImage(profileImageView, cursor.getString(indices.quoted_by_user_profile_image));
|
||||
|
||||
typeIconRes = getUserTypeIconRes(cursor.getShort(indices.quoted_by_user_is_verified) == 1,
|
||||
cursor.getShort(indices.quoted_by_user_is_protected) == 1);
|
||||
} else {
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
|
||||
typeIconRes = 0;
|
||||
}
|
||||
|
||||
itemContent.drawStart(manager.getUserColor(cursor.getLong(indices.quoted_by_user_id), false),
|
||||
manager.getUserColor(cursor.getLong(indices.user_id), false));
|
||||
|
||||
} else {
|
||||
nameView.setName(manager.getUserNickname(user_id, user_name, false));
|
||||
nameView.setScreenName("@" + user_screen_name);
|
||||
if (retweet_id > 0) {
|
||||
timeView.setTime(cursor.getLong(indices.retweet_timestamp));
|
||||
} else {
|
||||
timeView.setTime(cursor.getLong(indices.status_timestamp));
|
||||
}
|
||||
|
||||
quotedNameView.setVisibility(View.GONE);
|
||||
quoteTextView.setVisibility(View.GONE);
|
||||
quoteIndicator.setVisibility(View.GONE);
|
||||
|
||||
if (adapter.isProfileImageEnabled()) {
|
||||
profileImageView.setVisibility(View.VISIBLE);
|
||||
|
||||
final String user_profile_image_url = cursor.getString(indices.user_profile_image_url);
|
||||
loader.displayProfileImage(profileImageView, user_profile_image_url);
|
||||
|
||||
typeIconRes = getUserTypeIconRes(cursor.getShort(indices.is_verified) == 1,
|
||||
cursor.getShort(indices.is_protected) == 1);
|
||||
} else {
|
||||
profileImageView.setVisibility(View.GONE);
|
||||
loader.cancelDisplayTask(profileImageView);
|
||||
|
||||
typeIconRes = 0;
|
||||
}
|
||||
if (retweet_id > 0) {
|
||||
itemContent.drawStart(manager.getUserColor(retweeted_by_id, false), manager.getUserColor(user_id, false));
|
||||
} else {
|
||||
itemContent.drawStart(manager.getUserColor(user_id, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (typeIconRes != 0) {
|
||||
profileTypeView.setImageResource(typeIconRes);
|
||||
profileTypeView.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
profileTypeView.setImageDrawable(null);
|
||||
profileTypeView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (adapter.shouldShowAccountsColor()) {
|
||||
itemContent.drawEnd(Utils.getAccountColor(context, account_id));
|
||||
} else {
|
||||
itemContent.drawEnd();
|
||||
}
|
||||
|
||||
|
||||
if (adapter.isMediaPreviewEnabled()) {
|
||||
final boolean hasMedia = media != null && media.length > 0;
|
||||
if (hasMedia && (adapter.isSensitiveContentEnabled() || !sensitive)) {
|
||||
mediaPreview.setVisibility(View.VISIBLE);
|
||||
mediaPreview.displayMedia(media, loader, account_id, this, adapter.getMediaLoadingHandler());
|
||||
} else {
|
||||
mediaPreview.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
mediaPreview.setVisibility(View.GONE);
|
||||
}
|
||||
if (adapter.getLinkHighlightingStyle() == VALUE_LINK_HIGHLIGHT_OPTION_CODE_NONE) {
|
||||
textView.setText(cursor.getString(indices.text_unescaped));
|
||||
} else {
|
||||
textView.setText(Html.fromHtml(cursor.getString(indices.text_html)));
|
||||
linkify.applyAllLinks(textView, account_id, getLayoutPosition(),
|
||||
cursor.getShort(indices.is_possibly_sensitive) == 1,
|
||||
adapter.getLinkHighlightingStyle());
|
||||
textView.setMovementMethod(null);
|
||||
}
|
||||
|
||||
if (reply_count > 0) {
|
||||
replyCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), reply_count));
|
||||
} else {
|
||||
replyCountView.setText(null);
|
||||
}
|
||||
|
||||
if (twitter.isDestroyingStatus(account_id, my_retweet_id)) {
|
||||
retweetCountView.setActivated(false);
|
||||
retweet_count = Math.max(0, cursor.getLong(is_quote ? indices.quote_retweet_count : indices.retweet_count) - 1);
|
||||
} else {
|
||||
final boolean creatingRetweet = twitter.isCreatingRetweet(account_id, status_id);
|
||||
retweetCountView.setActivated(creatingRetweet || Utils.isMyRetweet(account_id,
|
||||
retweeted_by_id, my_retweet_id));
|
||||
retweet_count = cursor.getLong(is_quote ? indices.quote_retweet_count : indices.retweet_count) + (creatingRetweet ? 1 : 0);
|
||||
}
|
||||
if (retweet_count > 0) {
|
||||
retweetCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), retweet_count));
|
||||
} else {
|
||||
retweetCountView.setText(null);
|
||||
}
|
||||
if (twitter.isDestroyingFavorite(account_id, status_id)) {
|
||||
favoriteCountView.setActivated(false);
|
||||
favorite_count = Math.max(0, cursor.getLong(is_quote ? indices.quote_favorite_count : indices.favorite_count) - 1);
|
||||
} else {
|
||||
final boolean creatingFavorite = twitter.isCreatingFavorite(account_id, status_id);
|
||||
favoriteCountView.setActivated(creatingFavorite || cursor.getShort(indices.is_favorite) == 1);
|
||||
favorite_count = cursor.getLong(is_quote ? indices.quote_favorite_count : indices.favorite_count) + (creatingFavorite ? 1 : 0);
|
||||
}
|
||||
if (favorite_count > 0) {
|
||||
favoriteCountView.setText(Utils.getLocalizedNumber(Locale.getDefault(), favorite_count));
|
||||
} else {
|
||||
favoriteCountView.setText(null);
|
||||
}
|
||||
displayExtraTypeIcon(card_name, media, location, place_full_name, sensitive);
|
||||
|
||||
nameView.updateText();
|
||||
quotedNameView.updateText();
|
||||
}
|
||||
|
||||
public CardView getCardView() {
|
||||
return (CardView) itemView.findViewById(R.id.card);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user