mirror of
https://github.com/KokaKiwi/BarInsta
synced 2024-11-26 00:27:30 +00:00
Migrate to Room
This commit is contained in:
parent
126a0f7f4b
commit
6b8df5fee2
229
app/src/main/java/awais/instagrabber/db/AppDatabase.java
Normal file
229
app/src/main/java/awais/instagrabber/db/AppDatabase.java
Normal file
@ -0,0 +1,229 @@
|
||||
package awais.instagrabber.db;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.room.Database;
|
||||
import androidx.room.Room;
|
||||
import androidx.room.RoomDatabase;
|
||||
import androidx.room.TypeConverters;
|
||||
import androidx.room.migration.Migration;
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.db.dao.AccountDao;
|
||||
import awais.instagrabber.db.dao.FavoriteDao;
|
||||
import awais.instagrabber.db.entities.Account;
|
||||
import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.utils.Utils;
|
||||
|
||||
@Database(entities = {Account.class, Favorite.class},
|
||||
version = 4)
|
||||
@TypeConverters({Converters.class})
|
||||
public abstract class AppDatabase extends RoomDatabase {
|
||||
private static final String TAG = AppDatabase.class.getSimpleName();
|
||||
|
||||
private static AppDatabase INSTANCE;
|
||||
|
||||
public abstract AccountDao accountDao();
|
||||
|
||||
public abstract FavoriteDao favoriteDao();
|
||||
|
||||
public static AppDatabase getDatabase(final Context context) {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (AppDatabase.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), AppDatabase.class, "cookiebox.db")
|
||||
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_FULL_NAME + " TEXT");
|
||||
db.execSQL("ALTER TABLE cookies ADD " + Account.COL_PROFILE_PIC + " TEXT");
|
||||
}
|
||||
};
|
||||
|
||||
static final Migration MIGRATION_2_3 = new Migration(2, 3) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
final List<Favorite> oldFavorites = backupOldFavorites(db);
|
||||
// recreate with new columns (as there will be no doubt about the `query_display` column being present or not in the future versions)
|
||||
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME);
|
||||
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + " ("
|
||||
+ Favorite.COL_ID + " INTEGER PRIMARY KEY,"
|
||||
+ Favorite.COL_QUERY + " TEXT,"
|
||||
+ Favorite.COL_TYPE + " TEXT,"
|
||||
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
|
||||
+ Favorite.COL_PIC_URL + " TEXT,"
|
||||
+ Favorite.COL_DATE_ADDED + " INTEGER)");
|
||||
// add the old favorites back
|
||||
for (final Favorite oldFavorite : oldFavorites) {
|
||||
insertOrUpdateFavorite(db, oldFavorite);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static final Migration MIGRATION_3_4 = new Migration(3, 4) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase db) {
|
||||
// Required when migrating to Room.
|
||||
// The original table primary keys were not 'NOT NULL', so the migration to Room were failing without the below migration.
|
||||
// Taking this opportunity to rename cookies table to accounts
|
||||
|
||||
// Create new table with name 'accounts'
|
||||
db.execSQL("CREATE TABLE " + Account.TABLE_NAME + " ("
|
||||
+ Account.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
|
||||
+ Account.COL_UID + " TEXT,"
|
||||
+ Account.COL_USERNAME + " TEXT,"
|
||||
+ Account.COL_COOKIE + " TEXT,"
|
||||
+ Account.COL_FULL_NAME + " TEXT,"
|
||||
+ Account.COL_PROFILE_PIC + " TEXT)");
|
||||
// Insert all data from table 'cookies' to 'accounts'
|
||||
db.execSQL("INSERT INTO " + Account.TABLE_NAME + " ("
|
||||
+ Account.COL_UID + ","
|
||||
+ Account.COL_USERNAME + ","
|
||||
+ Account.COL_COOKIE + ","
|
||||
+ Account.COL_FULL_NAME + ","
|
||||
+ Account.COL_PROFILE_PIC + ") "
|
||||
+ "SELECT "
|
||||
+ Account.COL_UID + ","
|
||||
+ Account.COL_USERNAME + ","
|
||||
+ Account.COL_COOKIE + ","
|
||||
+ Account.COL_FULL_NAME + ","
|
||||
+ Account.COL_PROFILE_PIC
|
||||
+ " FROM cookies");
|
||||
// Drop old cookies table
|
||||
db.execSQL("DROP TABLE cookies");
|
||||
|
||||
// Create favorite backup table
|
||||
db.execSQL("CREATE TABLE " + Favorite.TABLE_NAME + "_backup ("
|
||||
+ Favorite.COL_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,"
|
||||
+ Favorite.COL_QUERY + " TEXT,"
|
||||
+ Favorite.COL_TYPE + " TEXT,"
|
||||
+ Favorite.COL_DISPLAY_NAME + " TEXT,"
|
||||
+ Favorite.COL_PIC_URL + " TEXT,"
|
||||
+ Favorite.COL_DATE_ADDED + " INTEGER)");
|
||||
// Insert all data from table 'favorite' to 'favorite_backup'
|
||||
db.execSQL("INSERT INTO " + Favorite.TABLE_NAME + "_backup ("
|
||||
+ Favorite.COL_QUERY + ","
|
||||
+ Favorite.COL_TYPE + ","
|
||||
+ Favorite.COL_DISPLAY_NAME + ","
|
||||
+ Favorite.COL_PIC_URL + ","
|
||||
+ Favorite.COL_DATE_ADDED + ") "
|
||||
+ "SELECT "
|
||||
+ Favorite.COL_QUERY + ","
|
||||
+ Favorite.COL_TYPE + ","
|
||||
+ Favorite.COL_DISPLAY_NAME + ","
|
||||
+ Favorite.COL_PIC_URL + ","
|
||||
+ Favorite.COL_DATE_ADDED
|
||||
+ " FROM " + Favorite.TABLE_NAME);
|
||||
// Drop favorites
|
||||
db.execSQL("DROP TABLE " + Favorite.TABLE_NAME);
|
||||
// Rename favorite_backup to favorites
|
||||
db.execSQL("ALTER TABLE " + Favorite.TABLE_NAME + "_backup RENAME TO " + Favorite.TABLE_NAME);
|
||||
}
|
||||
};
|
||||
|
||||
@NonNull
|
||||
private static List<Favorite> backupOldFavorites(@NonNull final SupportSQLiteDatabase db) {
|
||||
// check if old favorites table had the column query_display
|
||||
final boolean queryDisplayExists = checkColumnExists(db, Favorite.TABLE_NAME, "query_display");
|
||||
Log.d(TAG, "backupOldFavorites: queryDisplayExists: " + queryDisplayExists);
|
||||
final List<Favorite> oldModels = new ArrayList<>();
|
||||
final String sql = "SELECT "
|
||||
+ "query_text,"
|
||||
+ "date_added"
|
||||
+ (queryDisplayExists ? ",query_display" : "")
|
||||
+ " FROM " + Favorite.TABLE_NAME;
|
||||
try (final Cursor cursor = db.query(sql)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
try {
|
||||
final String queryText = cursor.getString(cursor.getColumnIndex("query_text"));
|
||||
final Pair<FavoriteType, String> favoriteTypeQueryPair = Utils.migrateOldFavQuery(queryText);
|
||||
if (favoriteTypeQueryPair == null) continue;
|
||||
final FavoriteType type = favoriteTypeQueryPair.first;
|
||||
final String query = favoriteTypeQueryPair.second;
|
||||
oldModels.add(new Favorite(
|
||||
-1,
|
||||
query,
|
||||
type,
|
||||
queryDisplayExists ? cursor.getString(cursor.getColumnIndex("query_display"))
|
||||
: null,
|
||||
null,
|
||||
new Date(cursor.getLong(cursor.getColumnIndex("date_added")))
|
||||
));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onUpgrade", e);
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onUpgrade", e);
|
||||
}
|
||||
Log.d(TAG, "backupOldFavorites: oldModels:" + oldModels);
|
||||
return oldModels;
|
||||
}
|
||||
|
||||
private static synchronized void insertOrUpdateFavorite(@NonNull final SupportSQLiteDatabase db, @NonNull final Favorite model) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(Favorite.COL_QUERY, model.getQuery());
|
||||
values.put(Favorite.COL_TYPE, model.getType().toString());
|
||||
values.put(Favorite.COL_DISPLAY_NAME, model.getDisplayName());
|
||||
values.put(Favorite.COL_PIC_URL, model.getPicUrl());
|
||||
values.put(Favorite.COL_DATE_ADDED, model.getDateAdded().getTime());
|
||||
int rows;
|
||||
if (model.getId() >= 1) {
|
||||
rows = db.update(Favorite.TABLE_NAME,
|
||||
SQLiteDatabase.CONFLICT_IGNORE,
|
||||
values,
|
||||
Favorite.COL_ID + "=?",
|
||||
new String[]{String.valueOf(model.getId())});
|
||||
} else {
|
||||
rows = db.update(Favorite.TABLE_NAME,
|
||||
SQLiteDatabase.CONFLICT_IGNORE,
|
||||
values,
|
||||
Favorite.COL_QUERY + "=?" + " AND " + Favorite.COL_TYPE + "=?",
|
||||
new String[]{model.getQuery(), model.getType().toString()});
|
||||
}
|
||||
if (rows != 1) {
|
||||
db.insert(Favorite.TABLE_NAME, SQLiteDatabase.CONFLICT_IGNORE, values);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkColumnExists(@NonNull final SupportSQLiteDatabase db,
|
||||
@NonNull final String tableName,
|
||||
@NonNull final String columnName) {
|
||||
boolean exists = false;
|
||||
try (Cursor cursor = db.query("PRAGMA table_info(" + tableName + ")")) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
|
||||
if (currentColumn.equals(columnName)) {
|
||||
exists = true;
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "checkColumnExists", ex);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
}
|
33
app/src/main/java/awais/instagrabber/db/Converters.java
Normal file
33
app/src/main/java/awais/instagrabber/db/Converters.java
Normal file
@ -0,0 +1,33 @@
|
||||
package awais.instagrabber.db;
|
||||
|
||||
import androidx.room.TypeConverter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
|
||||
public class Converters {
|
||||
@TypeConverter
|
||||
public static Date fromTimestamp(Long value) {
|
||||
return value == null ? null : new Date(value);
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static Long dateToTimestamp(Date date) {
|
||||
return date == null ? null : date.getTime();
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static FavoriteType fromFavoriteTypeString(String value) {
|
||||
try {
|
||||
return FavoriteType.valueOf(value);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
public static String favoriteTypeToString(FavoriteType favoriteType) {
|
||||
return favoriteType == null ? null : favoriteType.toString();
|
||||
}
|
||||
}
|
34
app/src/main/java/awais/instagrabber/db/dao/AccountDao.java
Normal file
34
app/src/main/java/awais/instagrabber/db/dao/AccountDao.java
Normal file
@ -0,0 +1,34 @@
|
||||
package awais.instagrabber.db.dao;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.db.entities.Account;
|
||||
|
||||
@Dao
|
||||
public interface AccountDao {
|
||||
|
||||
@Query("SELECT * FROM accounts")
|
||||
List<Account> getAllAccounts();
|
||||
|
||||
@Query("SELECT * FROM accounts WHERE uid = :uid")
|
||||
Account findAccountByUid(String uid);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
List<Long> insertAccounts(Account... accounts);
|
||||
|
||||
@Update
|
||||
void updateAccounts(Account... accounts);
|
||||
|
||||
@Delete
|
||||
void deleteAccounts(Account... accounts);
|
||||
|
||||
@Query("DELETE from accounts")
|
||||
void deleteAllAccounts();
|
||||
}
|
35
app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.java
Normal file
35
app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.java
Normal file
@ -0,0 +1,35 @@
|
||||
package awais.instagrabber.db.dao;
|
||||
|
||||
import androidx.room.Dao;
|
||||
import androidx.room.Delete;
|
||||
import androidx.room.Insert;
|
||||
import androidx.room.OnConflictStrategy;
|
||||
import androidx.room.Query;
|
||||
import androidx.room.Update;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
|
||||
@Dao
|
||||
public interface FavoriteDao {
|
||||
|
||||
@Query("SELECT * FROM favorites")
|
||||
List<Favorite> getAllFavorites();
|
||||
|
||||
@Query("SELECT * FROM favorites WHERE query_text = :query and type = :type")
|
||||
Favorite findFavoriteByQueryAndType(String query, FavoriteType type);
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
List<Long> insertFavorites(Favorite... favorites);
|
||||
|
||||
@Update
|
||||
void updateFavorites(Favorite... favorites);
|
||||
|
||||
@Delete
|
||||
void deleteFavorites(Favorite... favorites);
|
||||
|
||||
@Query("DELETE from favorites")
|
||||
void deleteAllFavorites();
|
||||
}
|
@ -1,182 +1,68 @@
|
||||
package awais.instagrabber.db.datasources;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.db.AppDatabase;
|
||||
import awais.instagrabber.db.dao.AccountDao;
|
||||
import awais.instagrabber.db.entities.Account;
|
||||
import awais.instagrabber.utils.DataBox;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
|
||||
import static awais.instagrabber.utils.DataBox.KEY_COOKIE;
|
||||
import static awais.instagrabber.utils.DataBox.KEY_FULL_NAME;
|
||||
import static awais.instagrabber.utils.DataBox.KEY_ID;
|
||||
import static awais.instagrabber.utils.DataBox.KEY_PROFILE_PIC;
|
||||
import static awais.instagrabber.utils.DataBox.KEY_UID;
|
||||
import static awais.instagrabber.utils.DataBox.KEY_USERNAME;
|
||||
import static awais.instagrabber.utils.DataBox.TABLE_COOKIES;
|
||||
|
||||
public class AccountDataSource {
|
||||
private static final String TAG = AccountDataSource.class.getSimpleName();
|
||||
|
||||
private static AccountDataSource INSTANCE;
|
||||
|
||||
private final DataBox dataBox;
|
||||
private final AccountDao accountDao;
|
||||
|
||||
private AccountDataSource(@NonNull Context context) {
|
||||
dataBox = DataBox.getInstance(context);
|
||||
private AccountDataSource(final AccountDao accountDao) {
|
||||
this.accountDao = accountDao;
|
||||
}
|
||||
|
||||
public static synchronized AccountDataSource getInstance(@NonNull Context context) {
|
||||
public static AccountDataSource getInstance(@NonNull Context context) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new AccountDataSource(context);
|
||||
synchronized (AccountDataSource.class) {
|
||||
if (INSTANCE == null) {
|
||||
final AppDatabase database = AppDatabase.getDatabase(context);
|
||||
INSTANCE = new AccountDataSource(database.accountDao());
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final Account getAccount(final String uid) {
|
||||
Account cookie = null;
|
||||
try (final SQLiteDatabase db = dataBox.getReadableDatabase();
|
||||
final Cursor cursor = db.query(TABLE_COOKIES,
|
||||
new String[]{
|
||||
KEY_ID,
|
||||
KEY_UID,
|
||||
KEY_USERNAME,
|
||||
KEY_COOKIE,
|
||||
KEY_FULL_NAME,
|
||||
KEY_PROFILE_PIC
|
||||
},
|
||||
KEY_UID + "=?",
|
||||
new String[]{uid},
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor != null && cursor.moveToFirst())
|
||||
cookie = new Account(
|
||||
cursor.getInt(cursor.getColumnIndex(KEY_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_UID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_USERNAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_COOKIE)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_FULL_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_PROFILE_PIC))
|
||||
);
|
||||
}
|
||||
return cookie;
|
||||
return accountDao.findAccountByUid(uid);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public final List<Account> getAllAccounts() {
|
||||
final List<Account> cookies = new ArrayList<>();
|
||||
try (final SQLiteDatabase db = dataBox.getReadableDatabase();
|
||||
final Cursor cursor = db.query(TABLE_COOKIES,
|
||||
new String[]{
|
||||
KEY_ID,
|
||||
KEY_UID,
|
||||
KEY_USERNAME,
|
||||
KEY_COOKIE,
|
||||
KEY_FULL_NAME,
|
||||
KEY_PROFILE_PIC
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
cookies.add(new Account(
|
||||
cursor.getInt(cursor.getColumnIndex(KEY_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_UID)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_USERNAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_COOKIE)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_FULL_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(KEY_PROFILE_PIC))
|
||||
));
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
}
|
||||
return cookies;
|
||||
return accountDao.getAllAccounts();
|
||||
}
|
||||
|
||||
// public final void insertOrUpdateAccount(@NonNull final Account account) {
|
||||
// insertOrUpdateAccount(
|
||||
// account.getUid(),
|
||||
// account.getUsername(),
|
||||
// account.getCookie(),
|
||||
// account.getFullName(),
|
||||
// account.getProfilePic()
|
||||
// );
|
||||
// }
|
||||
|
||||
public final void insertOrUpdateAccount(final String uid,
|
||||
final String username,
|
||||
final String cookie,
|
||||
final String fullName,
|
||||
final String profilePicUrl) {
|
||||
if (TextUtils.isEmpty(uid)) return;
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(KEY_USERNAME, username);
|
||||
values.put(KEY_COOKIE, cookie);
|
||||
values.put(KEY_UID, uid);
|
||||
values.put(KEY_FULL_NAME, fullName);
|
||||
values.put(KEY_PROFILE_PIC, profilePicUrl);
|
||||
final int rows = db.update(TABLE_COOKIES, values, KEY_UID + "=?", new String[]{uid});
|
||||
if (rows != 1) {
|
||||
db.insert(TABLE_COOKIES, null, values);
|
||||
}
|
||||
db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (BuildConfig.DEBUG) Log.e(TAG, "Error", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
final Account account = getAccount(uid);
|
||||
final Account toUpdate = new Account(account == null ? 0 : account.getId(), uid, username, cookie, fullName, profilePicUrl);
|
||||
if (account != null) {
|
||||
accountDao.updateAccounts(toUpdate);
|
||||
return;
|
||||
}
|
||||
accountDao.insertAccounts(toUpdate);
|
||||
}
|
||||
|
||||
public final synchronized void deleteAccount(@NonNull final Account account) {
|
||||
final String cookieModelUid = account.getUid();
|
||||
if (!TextUtils.isEmpty(cookieModelUid)) {
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final int rowsDeleted = db.delete(TABLE_COOKIES, KEY_UID + "=? AND " + KEY_USERNAME + "=? AND " + KEY_COOKIE + "=?",
|
||||
new String[]{cookieModelUid, account.getUsername(), account.getCookie()});
|
||||
|
||||
if (rowsDeleted > 0) db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
public final void deleteAccount(@NonNull final Account account) {
|
||||
accountDao.deleteAccounts(account);
|
||||
}
|
||||
|
||||
public final synchronized void deleteAllAccounts() {
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final int rowsDeleted = db.delete(TABLE_COOKIES, null, null);
|
||||
|
||||
if (rowsDeleted > 0) db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (BuildConfig.DEBUG) Log.e("AWAISKING_APP", "", e);
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
public final void deleteAllAccounts() {
|
||||
accountDao.deleteAllAccounts();
|
||||
}
|
||||
}
|
||||
|
@ -1,180 +1,62 @@
|
||||
package awais.instagrabber.db.datasources;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.BuildConfig;
|
||||
import awais.instagrabber.db.AppDatabase;
|
||||
import awais.instagrabber.db.dao.FavoriteDao;
|
||||
import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.utils.DataBox;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awaisomereport.LogCollector;
|
||||
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_DATE_ADDED;
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_DISPLAY_NAME;
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_ID;
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_PIC_URL;
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_QUERY;
|
||||
import static awais.instagrabber.utils.DataBox.FAV_COL_TYPE;
|
||||
import static awais.instagrabber.utils.DataBox.TABLE_FAVORITES;
|
||||
import static awais.instagrabber.utils.Utils.logCollector;
|
||||
|
||||
public class FavoriteDataSource {
|
||||
private static final String TAG = FavoriteDataSource.class.getSimpleName();
|
||||
|
||||
private static FavoriteDataSource INSTANCE;
|
||||
|
||||
private final DataBox dataBox;
|
||||
private final FavoriteDao favoriteDao;
|
||||
|
||||
private FavoriteDataSource(@NonNull Context context) {
|
||||
dataBox = DataBox.getInstance(context);
|
||||
private FavoriteDataSource(final FavoriteDao favoriteDao) {
|
||||
this.favoriteDao = favoriteDao;
|
||||
}
|
||||
|
||||
public static synchronized FavoriteDataSource getInstance(@NonNull Context context) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new FavoriteDataSource(context);
|
||||
synchronized (FavoriteDataSource.class) {
|
||||
if (INSTANCE == null) {
|
||||
final AppDatabase database = AppDatabase.getDatabase(context);
|
||||
INSTANCE = new FavoriteDataSource(database.favoriteDao());
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public final Favorite getFavorite(@NonNull final String query, @NonNull final FavoriteType type) {
|
||||
try (final SQLiteDatabase db = dataBox.getReadableDatabase();
|
||||
final Cursor cursor = db.query(TABLE_FAVORITES,
|
||||
new String[]{
|
||||
FAV_COL_ID,
|
||||
FAV_COL_QUERY,
|
||||
FAV_COL_TYPE,
|
||||
FAV_COL_DISPLAY_NAME,
|
||||
FAV_COL_PIC_URL,
|
||||
FAV_COL_DATE_ADDED
|
||||
},
|
||||
FAV_COL_QUERY + "=?" + " AND " + FAV_COL_TYPE + "=?",
|
||||
new String[]{
|
||||
query,
|
||||
type.toString()
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
FavoriteType favoriteType = null;
|
||||
try {
|
||||
favoriteType = FavoriteType.valueOf(cursor.getString(cursor.getColumnIndex(FAV_COL_TYPE)));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
return new Favorite(
|
||||
cursor.getInt(cursor.getColumnIndex(FAV_COL_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_QUERY)),
|
||||
favoriteType,
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_DISPLAY_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_PIC_URL)),
|
||||
new Date(cursor.getLong(cursor.getColumnIndex(FAV_COL_DATE_ADDED)))
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return favoriteDao.findFavoriteByQueryAndType(query, type);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public final List<Favorite> getAllFavorites() {
|
||||
final List<Favorite> favorites = new ArrayList<>();
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
try (final Cursor cursor = db.query(TABLE_FAVORITES,
|
||||
new String[]{
|
||||
FAV_COL_ID,
|
||||
FAV_COL_QUERY,
|
||||
FAV_COL_TYPE,
|
||||
FAV_COL_DISPLAY_NAME,
|
||||
FAV_COL_PIC_URL,
|
||||
FAV_COL_DATE_ADDED
|
||||
},
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
db.beginTransaction();
|
||||
Favorite tempFav;
|
||||
do {
|
||||
FavoriteType type = null;
|
||||
try {
|
||||
type = FavoriteType.valueOf(cursor.getString(cursor.getColumnIndex(FAV_COL_TYPE)));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
tempFav = new Favorite(
|
||||
cursor.getInt(cursor.getColumnIndex(FAV_COL_ID)),
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_QUERY)),
|
||||
type,
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_DISPLAY_NAME)),
|
||||
cursor.getString(cursor.getColumnIndex(FAV_COL_PIC_URL)),
|
||||
new Date(cursor.getLong(cursor.getColumnIndex(FAV_COL_DATE_ADDED)))
|
||||
);
|
||||
favorites.add(tempFav);
|
||||
} while (cursor.moveToNext());
|
||||
db.endTransaction();
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
Log.e(TAG, "", e);
|
||||
}
|
||||
}
|
||||
return favorites;
|
||||
return favoriteDao.getAllFavorites();
|
||||
}
|
||||
|
||||
public final synchronized Favorite insertOrUpdateFavorite(@NonNull final Favorite model) {
|
||||
final String query = model.getQuery();
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
dataBox.insertOrUpdateFavorite(db, model);
|
||||
db.setTransactionSuccessful();
|
||||
} catch (Exception e) {
|
||||
if (logCollector != null) {
|
||||
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "insertOrUpdateFavorite");
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.e(TAG, "Error adding/updating favorite", e);
|
||||
}
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
return getFavorite(model.getQuery(), model.getType());
|
||||
public final void insertOrUpdateFavorite(@NonNull final Favorite favorite) {
|
||||
if (favorite.getId() > 0) {
|
||||
favoriteDao.updateFavorites(favorite);
|
||||
return;
|
||||
}
|
||||
return null;
|
||||
favoriteDao.insertFavorites(favorite);
|
||||
}
|
||||
|
||||
public final synchronized void deleteFavorite(@NonNull final String query, @NonNull final FavoriteType type) {
|
||||
if (!TextUtils.isEmpty(query)) {
|
||||
try (final SQLiteDatabase db = dataBox.getWritableDatabase()) {
|
||||
db.beginTransaction();
|
||||
try {
|
||||
final int rowsDeleted = db.delete(TABLE_FAVORITES,
|
||||
FAV_COL_QUERY + "=?" +
|
||||
" AND " + FAV_COL_TYPE + "=?",
|
||||
new String[]{query, type.toString()});
|
||||
|
||||
if (rowsDeleted > 0) db.setTransactionSuccessful();
|
||||
} catch (final Exception e) {
|
||||
if (logCollector != null) {
|
||||
logCollector.appendException(e, LogCollector.LogFile.DATA_BOX_FAVORITES, "deleteFavorite");
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.e(TAG, "Error", e);
|
||||
}
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
}
|
||||
}
|
||||
public final void deleteFavorite(@NonNull final String query, @NonNull final FavoriteType type) {
|
||||
final Favorite favorite = getFavorite(query, type);
|
||||
if (favorite == null) return;
|
||||
favoriteDao.deleteFavorites(favorite);
|
||||
}
|
||||
}
|
||||
|
@ -4,32 +4,42 @@ import androidx.annotation.NonNull;
|
||||
import androidx.core.util.ObjectsCompat;
|
||||
import androidx.room.ColumnInfo;
|
||||
import androidx.room.Entity;
|
||||
import androidx.room.Ignore;
|
||||
import androidx.room.PrimaryKey;
|
||||
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
|
||||
@Entity(tableName = "cookies")
|
||||
@Entity(tableName = Account.TABLE_NAME)
|
||||
public class Account {
|
||||
public final static String TABLE_NAME = "accounts";
|
||||
public final static String COL_ID = "id";
|
||||
public final static String COL_USERNAME = Constants.EXTRAS_USERNAME;
|
||||
public final static String COL_COOKIE = "cookie";
|
||||
public final static String COL_UID = "uid";
|
||||
public final static String COL_FULL_NAME = "full_name";
|
||||
public final static String COL_PROFILE_PIC = "profile_pic";
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = "id")
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = COL_ID)
|
||||
private final int id;
|
||||
|
||||
@ColumnInfo(name = "uid")
|
||||
@ColumnInfo(name = COL_UID)
|
||||
private final String uid;
|
||||
|
||||
@ColumnInfo(name = "username")
|
||||
@ColumnInfo(name = COL_USERNAME)
|
||||
private final String username;
|
||||
|
||||
@ColumnInfo(name = "cookie")
|
||||
@ColumnInfo(name = COL_COOKIE)
|
||||
private final String cookie;
|
||||
|
||||
@ColumnInfo(name = "full_name")
|
||||
@ColumnInfo(name = COL_FULL_NAME)
|
||||
private final String fullName;
|
||||
|
||||
@ColumnInfo(name = "profile_pic")
|
||||
@ColumnInfo(name = COL_PROFILE_PIC)
|
||||
private final String profilePic;
|
||||
|
||||
@Ignore
|
||||
private boolean selected;
|
||||
|
||||
public Account(final int id,
|
||||
|
@ -10,26 +10,33 @@ import java.util.Date;
|
||||
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
|
||||
@Entity(tableName = "favorites")
|
||||
@Entity(tableName = Favorite.TABLE_NAME)
|
||||
public class Favorite {
|
||||
public final static String TABLE_NAME = "favorites";
|
||||
public final static String COL_ID = "id";
|
||||
public final static String COL_QUERY = "query_text";
|
||||
public final static String COL_TYPE = "type";
|
||||
public final static String COL_DISPLAY_NAME = "display_name";
|
||||
public final static String COL_PIC_URL = "pic_url";
|
||||
public final static String COL_DATE_ADDED = "date_added";
|
||||
|
||||
@PrimaryKey
|
||||
@ColumnInfo(name = "id")
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@ColumnInfo(name = COL_ID)
|
||||
private final int id;
|
||||
|
||||
@ColumnInfo(name = "query_text")
|
||||
@ColumnInfo(name = COL_QUERY)
|
||||
private final String query;
|
||||
|
||||
@ColumnInfo(name = "type")
|
||||
@ColumnInfo(name = COL_TYPE)
|
||||
private final FavoriteType type;
|
||||
|
||||
@ColumnInfo(name = "display_name")
|
||||
@ColumnInfo(name = COL_DISPLAY_NAME)
|
||||
private final String displayName;
|
||||
|
||||
@ColumnInfo(name = "pic_url")
|
||||
@ColumnInfo(name = COL_PIC_URL)
|
||||
private final String picUrl;
|
||||
|
||||
@ColumnInfo(name = "date_added")
|
||||
@ColumnInfo(name = COL_DATE_ADDED)
|
||||
private final Date dateAdded;
|
||||
|
||||
public Favorite(final int id,
|
||||
|
@ -21,9 +21,9 @@ public class AccountRepository {
|
||||
this.accountDataSource = accountDataSource;
|
||||
}
|
||||
|
||||
public static AccountRepository getInstance(final AppExecutors appExecutors, final AccountDataSource accountDataSource) {
|
||||
public static AccountRepository getInstance(final AccountDataSource accountDataSource) {
|
||||
if (instance == null) {
|
||||
instance = new AccountRepository(appExecutors, accountDataSource);
|
||||
instance = new AccountRepository(AppExecutors.getInstance(), accountDataSource);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
@ -20,9 +20,9 @@ public class FavoriteRepository {
|
||||
this.favoriteDataSource = favoriteDataSource;
|
||||
}
|
||||
|
||||
public static FavoriteRepository getInstance(final AppExecutors appExecutors, final FavoriteDataSource favoriteDataSource) {
|
||||
public static FavoriteRepository getInstance(final FavoriteDataSource favoriteDataSource) {
|
||||
if (instance == null) {
|
||||
instance = new FavoriteRepository(appExecutors, favoriteDataSource);
|
||||
instance = new FavoriteRepository(AppExecutors.getInstance(), favoriteDataSource);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
@ -60,18 +60,14 @@ public class FavoriteRepository {
|
||||
}
|
||||
|
||||
public void insertOrUpdateFavorite(final Favorite favorite,
|
||||
final RepositoryCallback<Favorite> callback) {
|
||||
final RepositoryCallback<Void> callback) {
|
||||
// request on the I/O thread
|
||||
appExecutors.diskIO().execute(() -> {
|
||||
final Favorite updated = favoriteDataSource.insertOrUpdateFavorite(favorite);
|
||||
favoriteDataSource.insertOrUpdateFavorite(favorite);
|
||||
// notify on the main thread
|
||||
appExecutors.mainThread().execute(() -> {
|
||||
if (callback == null) return;
|
||||
if (updated == null) {
|
||||
callback.onDataNotAvailable();
|
||||
return;
|
||||
}
|
||||
callback.onSuccess(updated);
|
||||
callback.onSuccess(null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import awais.instagrabber.db.datasources.AccountDataSource;
|
||||
import awais.instagrabber.db.entities.Account;
|
||||
import awais.instagrabber.db.repositories.AccountRepository;
|
||||
import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
@ -41,12 +40,12 @@ public class AccountSwitcherDialogFragment extends DialogFragment {
|
||||
private DialogAccountSwitcherBinding binding;
|
||||
|
||||
public AccountSwitcherDialogFragment() {
|
||||
accountRepository = AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(getContext()));
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
}
|
||||
|
||||
public AccountSwitcherDialogFragment(final OnAddAccountClickListener onAddAccountClickListener) {
|
||||
this.onAddAccountClickListener = onAddAccountClickListener;
|
||||
accountRepository = AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(getContext()));
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
}
|
||||
|
||||
private final AccountSwitcherAdapter.OnAccountClickListener accountClickListener = (model, isCurrent) -> {
|
||||
|
@ -32,7 +32,6 @@ import awais.instagrabber.db.datasources.FavoriteDataSource;
|
||||
import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.db.repositories.FavoriteRepository;
|
||||
import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.TextUtils;
|
||||
import awais.instagrabber.viewmodels.FavoritesViewModel;
|
||||
|
||||
@ -49,7 +48,7 @@ public class FavoritesFragment extends Fragment {
|
||||
@Override
|
||||
public void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
favoriteRepository = FavoriteRepository.getInstance(new AppExecutors(), FavoriteDataSource.getInstance(getContext()));
|
||||
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@ -186,9 +185,9 @@ public class FavoritesFragment extends Fragment {
|
||||
result.getSdProfilePic(),
|
||||
model.getDateAdded()
|
||||
);
|
||||
favoriteRepository.insertOrUpdateFavorite(updated, new RepositoryCallback<Favorite>() {
|
||||
favoriteRepository.insertOrUpdateFavorite(updated, new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
public void onSuccess(final Void result) {
|
||||
updatedList.add(i, updated);
|
||||
try {
|
||||
cyclicBarrier.await();
|
||||
@ -225,9 +224,9 @@ public class FavoritesFragment extends Fragment {
|
||||
result.getSdProfilePic(),
|
||||
model.getDateAdded()
|
||||
);
|
||||
favoriteRepository.insertOrUpdateFavorite(updated, new RepositoryCallback<Favorite>() {
|
||||
favoriteRepository.insertOrUpdateFavorite(updated, new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
public void onSuccess(final Void result) {
|
||||
try {
|
||||
cyclicBarrier.await();
|
||||
} catch (BrokenBarrierException | InterruptedException e) {
|
||||
|
@ -59,7 +59,6 @@ import awais.instagrabber.models.HashtagModel;
|
||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
@ -459,8 +458,7 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
hashtagDetailsBinding.btnFollowTag.setVisibility(View.GONE);
|
||||
}
|
||||
hashtagDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository
|
||||
.getInstance(new AppExecutors(), FavoriteDataSource.getInstance(getContext()));
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
favoriteRepository.getFavorite(hashtag.substring(1), FavoriteType.HASHTAG, new RepositoryCallback<Favorite>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
@ -500,9 +498,9 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
hashtagModel.getName(),
|
||||
null,
|
||||
new Date()
|
||||
), new RepositoryCallback<Favorite>() {
|
||||
), new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
public void onSuccess(final Void result) {
|
||||
hashtagDetailsBinding.favChip.setText(R.string.favorite_short);
|
||||
hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24);
|
||||
showSnackbar(getString(R.string.added_to_favs));
|
||||
|
@ -62,7 +62,6 @@ import awais.instagrabber.models.LocationModel;
|
||||
import awais.instagrabber.models.PostsLayoutPreferences;
|
||||
import awais.instagrabber.models.StoryModel;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
@ -448,7 +447,7 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
locationDetailsBinding.locationUrl.setText(TextUtils.getSpannableUrl(url));
|
||||
}
|
||||
final FavoriteDataSource dataSource = FavoriteDataSource.getInstance(getContext());
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(new AppExecutors(), dataSource);
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(dataSource);
|
||||
locationDetailsBinding.favChip.setVisibility(View.VISIBLE);
|
||||
favoriteRepository.getFavorite(locationId, FavoriteType.LOCATION, new RepositoryCallback<Favorite>() {
|
||||
@Override
|
||||
@ -491,9 +490,9 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR
|
||||
locationModel.getName(),
|
||||
locationModel.getSdProfilePic(),
|
||||
new Date()
|
||||
), new RepositoryCallback<Favorite>() {
|
||||
), new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
public void onSuccess(final Void result) {
|
||||
locationDetailsBinding.favChip.setText(R.string.favorite_short);
|
||||
locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24);
|
||||
showSnackbar(getString(R.string.added_to_favs));
|
||||
|
@ -82,7 +82,6 @@ import awais.instagrabber.models.enums.FavoriteType;
|
||||
import awais.instagrabber.models.enums.PostItemType;
|
||||
import awais.instagrabber.repositories.responses.FriendshipRepoChangeRootResponse;
|
||||
import awais.instagrabber.repositories.responses.FriendshipRepoRestrictRootResponse;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.DownloadUtils;
|
||||
@ -299,9 +298,8 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
fragmentActivity = (MainActivity) requireActivity();
|
||||
friendshipService = FriendshipService.getInstance();
|
||||
storiesService = StoriesService.getInstance();
|
||||
final AppExecutors appExecutors = new AppExecutors();
|
||||
accountRepository = AccountRepository.getInstance(appExecutors, AccountDataSource.getInstance(getContext()));
|
||||
favoriteRepository = FavoriteRepository.getInstance(appExecutors, FavoriteDataSource.getInstance(getContext()));
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext()));
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@ -907,9 +905,9 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe
|
||||
profileModel.getSdProfilePic(),
|
||||
new Date()
|
||||
);
|
||||
favoriteRepository.insertOrUpdateFavorite(model, new RepositoryCallback<Favorite>() {
|
||||
favoriteRepository.insertOrUpdateFavorite(model, new RepositoryCallback<Void>() {
|
||||
@Override
|
||||
public void onSuccess(final Favorite result) {
|
||||
public void onSuccess(final Void result) {
|
||||
profileDetailsBinding.favCb.setButtonDrawable(R.drawable.ic_star_check_24);
|
||||
profileDetailsBinding.favProgress.setVisibility(View.GONE);
|
||||
profileDetailsBinding.favCb.setVisibility(View.VISIBLE);
|
||||
|
@ -33,7 +33,6 @@ import awais.instagrabber.db.repositories.AccountRepository;
|
||||
import awais.instagrabber.db.repositories.RepositoryCallback;
|
||||
import awais.instagrabber.dialogs.AccountSwitcherDialogFragment;
|
||||
import awais.instagrabber.repositories.responses.UserInfo;
|
||||
import awais.instagrabber.utils.AppExecutors;
|
||||
import awais.instagrabber.utils.Constants;
|
||||
import awais.instagrabber.utils.CookieUtils;
|
||||
import awais.instagrabber.utils.FlavorTown;
|
||||
@ -49,7 +48,7 @@ public class MorePreferencesFragment extends BasePreferencesFragment {
|
||||
private final AccountRepository accountRepository;
|
||||
|
||||
public MorePreferencesFragment() {
|
||||
accountRepository = AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(getContext()));
|
||||
accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,37 +35,48 @@ import java.util.concurrent.Executors;
|
||||
*/
|
||||
public class AppExecutors {
|
||||
|
||||
// private static final int THREAD_COUNT = 3;
|
||||
private static final int THREAD_COUNT = 3;
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private static AppExecutors instance;
|
||||
|
||||
private final Executor diskIO;
|
||||
// private final Executor networkIO;
|
||||
private final Executor networkIO;
|
||||
private final Executor mainThread;
|
||||
private final ListeningExecutorService tasksThread;
|
||||
|
||||
private AppExecutors(Executor diskIO,
|
||||
// Executor networkIO,
|
||||
Executor networkIO,
|
||||
Executor mainThread,
|
||||
ListeningExecutorService tasksThread) {
|
||||
this.diskIO = diskIO;
|
||||
// this.networkIO = networkIO;
|
||||
this.networkIO = networkIO;
|
||||
this.mainThread = mainThread;
|
||||
this.tasksThread = tasksThread;
|
||||
}
|
||||
|
||||
public AppExecutors() {
|
||||
this(Executors.newSingleThreadExecutor(),
|
||||
// Executors.newFixedThreadPool(THREAD_COUNT),
|
||||
new MainThreadExecutor(),
|
||||
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)));
|
||||
public static AppExecutors getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (LOCK) {
|
||||
if (instance == null) {
|
||||
instance = new AppExecutors(Executors.newSingleThreadExecutor(),
|
||||
Executors.newFixedThreadPool(THREAD_COUNT),
|
||||
new MainThreadExecutor(),
|
||||
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
||||
public Executor diskIO() {
|
||||
return diskIO;
|
||||
}
|
||||
|
||||
// public Executor networkIO() {
|
||||
// return networkIO;
|
||||
// }
|
||||
public Executor networkIO() {
|
||||
return networkIO;
|
||||
}
|
||||
|
||||
|
||||
public ListeningExecutorService tasksThread() {
|
||||
|
@ -63,7 +63,7 @@ public final class CookieUtils {
|
||||
if (cookieStore == null) return;
|
||||
cookieStore.removeAll();
|
||||
try {
|
||||
AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(context))
|
||||
AccountRepository.getInstance(AccountDataSource.getInstance(context))
|
||||
.deleteAllAccounts(callback);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "setupCookies", e);
|
||||
|
@ -1,45 +1,19 @@
|
||||
package awais.instagrabber.utils;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import awais.instagrabber.db.entities.Favorite;
|
||||
import awais.instagrabber.models.enums.FavoriteType;
|
||||
|
||||
public final class DataBox extends SQLiteOpenHelper {
|
||||
private static final String TAG = "DataBox";
|
||||
|
||||
private static DataBox sInstance;
|
||||
|
||||
private final static int VERSION = 3;
|
||||
public final static String TABLE_COOKIES = "cookies";
|
||||
public final static String TABLE_FAVORITES = "favorites";
|
||||
|
||||
public final static String KEY_ID = "id";
|
||||
public final static String KEY_USERNAME = Constants.EXTRAS_USERNAME;
|
||||
public final static String KEY_COOKIE = "cookie";
|
||||
public final static String KEY_UID = "uid";
|
||||
public final static String KEY_FULL_NAME = "full_name";
|
||||
public final static String KEY_PROFILE_PIC = "profile_pic";
|
||||
|
||||
public final static String FAV_COL_ID = "id";
|
||||
public final static String FAV_COL_QUERY = "query_text";
|
||||
public final static String FAV_COL_TYPE = "type";
|
||||
public final static String FAV_COL_DISPLAY_NAME = "display_name";
|
||||
public final static String FAV_COL_PIC_URL = "pic_url";
|
||||
public final static String FAV_COL_DATE_ADDED = "date_added";
|
||||
|
||||
public static synchronized DataBox getInstance(final Context context) {
|
||||
if (sInstance == null) sInstance = new DataBox(context.getApplicationContext());
|
||||
@ -53,21 +27,6 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
@Override
|
||||
public void onCreate(@NonNull final SQLiteDatabase db) {
|
||||
Log.i(TAG, "Creating tables...");
|
||||
db.execSQL("CREATE TABLE " + TABLE_COOKIES + " ("
|
||||
+ KEY_ID + " INTEGER PRIMARY KEY,"
|
||||
+ KEY_UID + " TEXT,"
|
||||
+ KEY_USERNAME + " TEXT,"
|
||||
+ KEY_COOKIE + " TEXT,"
|
||||
+ KEY_FULL_NAME + " TEXT,"
|
||||
+ KEY_PROFILE_PIC + " TEXT)");
|
||||
// db.execSQL("CREATE TABLE favorites (id INTEGER PRIMARY KEY, query_text TEXT, date_added INTEGER, query_display TEXT)");
|
||||
db.execSQL("CREATE TABLE " + TABLE_FAVORITES + " ("
|
||||
+ FAV_COL_ID + " INTEGER PRIMARY KEY,"
|
||||
+ FAV_COL_QUERY + " TEXT,"
|
||||
+ FAV_COL_TYPE + " TEXT,"
|
||||
+ FAV_COL_DISPLAY_NAME + " TEXT,"
|
||||
+ FAV_COL_PIC_URL + " TEXT,"
|
||||
+ FAV_COL_DATE_ADDED + " INTEGER)");
|
||||
Log.i(TAG, "Tables created!");
|
||||
}
|
||||
|
||||
@ -77,107 +36,8 @@ public final class DataBox extends SQLiteOpenHelper {
|
||||
// switch without break, so that all migrations from a previous version to new are run
|
||||
switch (oldVersion) {
|
||||
case 1:
|
||||
db.execSQL("ALTER TABLE " + TABLE_COOKIES + " ADD " + KEY_FULL_NAME + " TEXT");
|
||||
db.execSQL("ALTER TABLE " + TABLE_COOKIES + " ADD " + KEY_PROFILE_PIC + " TEXT");
|
||||
case 2:
|
||||
final List<Favorite> oldFavorites = backupOldFavorites(db);
|
||||
// recreate with new columns (as there will be no doubt about the `query_display` column being present or not in the future versions)
|
||||
db.execSQL("DROP TABLE " + TABLE_FAVORITES);
|
||||
db.execSQL("CREATE TABLE " + TABLE_FAVORITES + " ("
|
||||
+ FAV_COL_ID + " INTEGER PRIMARY KEY,"
|
||||
+ FAV_COL_QUERY + " TEXT,"
|
||||
+ FAV_COL_TYPE + " TEXT,"
|
||||
+ FAV_COL_DISPLAY_NAME + " TEXT,"
|
||||
+ FAV_COL_PIC_URL + " TEXT,"
|
||||
+ FAV_COL_DATE_ADDED + " INTEGER)");
|
||||
// add the old favorites back
|
||||
for (final Favorite oldFavorite : oldFavorites) {
|
||||
insertOrUpdateFavorite(db, oldFavorite);
|
||||
}
|
||||
}
|
||||
Log.i(TAG, String.format("DB update from v%d to v%d completed!", oldVersion, newVersion));
|
||||
}
|
||||
|
||||
public synchronized void insertOrUpdateFavorite(@NonNull final SQLiteDatabase db, @NonNull final Favorite model) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(FAV_COL_QUERY, model.getQuery());
|
||||
values.put(FAV_COL_TYPE, model.getType().toString());
|
||||
values.put(FAV_COL_DISPLAY_NAME, model.getDisplayName());
|
||||
values.put(FAV_COL_PIC_URL, model.getPicUrl());
|
||||
values.put(FAV_COL_DATE_ADDED, model.getDateAdded().getTime());
|
||||
int rows;
|
||||
if (model.getId() >= 1) {
|
||||
rows = db.update(TABLE_FAVORITES, values, FAV_COL_ID + "=?", new String[]{String.valueOf(model.getId())});
|
||||
} else {
|
||||
rows = db.update(TABLE_FAVORITES,
|
||||
values,
|
||||
FAV_COL_QUERY + "=?" +
|
||||
" AND " + FAV_COL_TYPE + "=?",
|
||||
new String[]{model.getQuery(), model.getType().toString()});
|
||||
}
|
||||
if (rows != 1) {
|
||||
db.insert(TABLE_FAVORITES, null, values);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private List<Favorite> backupOldFavorites(@NonNull final SQLiteDatabase db) {
|
||||
// check if old favorites table had the column query_display
|
||||
final boolean queryDisplayExists = checkColumnExists(db, TABLE_FAVORITES, "query_display");
|
||||
Log.d(TAG, "backupOldFavorites: queryDisplayExists: " + queryDisplayExists);
|
||||
final List<Favorite> oldModels = new ArrayList<>();
|
||||
final String sql = "SELECT "
|
||||
+ "query_text,"
|
||||
+ "date_added"
|
||||
+ (queryDisplayExists ? ",query_display" : "")
|
||||
+ " FROM " + TABLE_FAVORITES;
|
||||
try (final Cursor cursor = db.rawQuery(sql, null)) {
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
do {
|
||||
try {
|
||||
final String queryText = cursor.getString(cursor.getColumnIndex("query_text"));
|
||||
final Pair<FavoriteType, String> favoriteTypeQueryPair = Utils.migrateOldFavQuery(queryText);
|
||||
if (favoriteTypeQueryPair == null) continue;
|
||||
final FavoriteType type = favoriteTypeQueryPair.first;
|
||||
final String query = favoriteTypeQueryPair.second;
|
||||
oldModels.add(new Favorite(
|
||||
-1,
|
||||
query,
|
||||
type,
|
||||
queryDisplayExists ? cursor.getString(cursor.getColumnIndex("query_display"))
|
||||
: null,
|
||||
null,
|
||||
new Date(cursor.getLong(cursor.getColumnIndex("date_added")))
|
||||
));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onUpgrade", e);
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onUpgrade", e);
|
||||
}
|
||||
Log.d(TAG, "backupOldFavorites: oldModels:" + oldModels);
|
||||
return oldModels;
|
||||
}
|
||||
|
||||
public boolean checkColumnExists(@NonNull final SQLiteDatabase db,
|
||||
@NonNull final String tableName,
|
||||
@NonNull final String columnName) {
|
||||
boolean exists = false;
|
||||
try (Cursor cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null)) {
|
||||
if (cursor.moveToFirst()) {
|
||||
do {
|
||||
final String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
|
||||
if (currentColumn.equals(columnName)) {
|
||||
exists = true;
|
||||
}
|
||||
} while (cursor.moveToNext());
|
||||
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "checkColumnExists", ex);
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
}
|
@ -198,7 +198,7 @@ public final class ExportImportUtils {
|
||||
: favsObject.optString("pic_url"),
|
||||
new Date(favsObject.getLong("d")));
|
||||
// Log.d(TAG, "importJson: favoriteModel: " + favoriteModel);
|
||||
FavoriteRepository.getInstance(new AppExecutors(), FavoriteDataSource.getInstance(context))
|
||||
FavoriteRepository.getInstance(FavoriteDataSource.getInstance(context))
|
||||
.insertOrUpdateFavorite(favorite, null);
|
||||
}
|
||||
}
|
||||
@ -225,7 +225,7 @@ public final class ExportImportUtils {
|
||||
Log.e(TAG, "importAccounts: Error parsing json", e);
|
||||
return;
|
||||
}
|
||||
AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(context))
|
||||
AccountRepository.getInstance(AccountDataSource.getInstance(context))
|
||||
.insertOrUpdateAccounts(accounts, null);
|
||||
}
|
||||
|
||||
@ -266,9 +266,8 @@ public final class ExportImportUtils {
|
||||
private static void getExportString(@ExportImportFlags final int flags,
|
||||
@NonNull final Context context,
|
||||
final OnExportStringCreatedCallback callback) {
|
||||
final AppExecutors appExecutors = new AppExecutors();
|
||||
final Handler innerHandler = new Handler();
|
||||
appExecutors.tasksThread().execute(() -> {
|
||||
AppExecutors.getInstance().tasksThread().execute(() -> {
|
||||
final CountDownLatch responseWaiter = new CountDownLatch(3);
|
||||
try {
|
||||
final JSONObject jsonObject = new JSONObject();
|
||||
@ -341,7 +340,7 @@ public final class ExportImportUtils {
|
||||
|
||||
private static void getFavorites(final Context context, final OnFavoritesJsonLoadedCallback callback) {
|
||||
final FavoriteDataSource dataSource = FavoriteDataSource.getInstance(context);
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(new AppExecutors(), dataSource);
|
||||
final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(dataSource);
|
||||
try {
|
||||
favoriteRepository.getAllFavorites(new RepositoryCallback<List<Favorite>>() {
|
||||
@Override
|
||||
@ -379,7 +378,7 @@ public final class ExportImportUtils {
|
||||
}
|
||||
|
||||
private static void getCookies(final Context context, final OnAccountJsonLoadedCallback callback) {
|
||||
final AccountRepository accountRepository = AccountRepository.getInstance(new AppExecutors(), AccountDataSource.getInstance(context));
|
||||
final AccountRepository accountRepository = AccountRepository.getInstance(AccountDataSource.getInstance(context));
|
||||
accountRepository.getAllAccounts(new RepositoryCallback<List<Account>>() {
|
||||
@Override
|
||||
public void onSuccess(final List<Account> accounts) {
|
||||
|
Loading…
Reference in New Issue
Block a user