mirror of
https://github.com/etesync/android
synced 2025-01-10 15:51:08 +00:00
JournalModel: persist collection info inside the model instead of sqlite
This change moves the collection info away from raw sqlite in favour of the requery ORM.
This commit is contained in:
parent
bd5beaaf91
commit
cee9576155
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2013 – 2016 Ricki Hirner (bitfire web engineering).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the GNU Public License v3.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.etesync.syncadapter.model;
|
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Collections;
|
|
||||||
import okhttp3.mockwebserver.MockWebServer;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class CollectionInfoTest {
|
|
||||||
|
|
||||||
MockWebServer server = new MockWebServer();
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testFromDB() {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
values.put(Collections.ID, 1);
|
|
||||||
values.put(Collections.SERVICE_ID, 1);
|
|
||||||
values.put(Collections.URL, "http://example.com");
|
|
||||||
values.put(Collections.READ_ONLY, 1);
|
|
||||||
values.put(Collections.DISPLAY_NAME, "display name");
|
|
||||||
values.put(Collections.DESCRIPTION, "description");
|
|
||||||
values.put(Collections.COLOR, 0xFFFF0000);
|
|
||||||
values.put(Collections.TIME_ZONE, "tzdata");
|
|
||||||
values.put(Collections.SUPPORTS_VEVENT, 1);
|
|
||||||
values.put(Collections.SUPPORTS_VTODO, 1);
|
|
||||||
values.put(Collections.SYNC, 1);
|
|
||||||
|
|
||||||
CollectionInfo info = CollectionInfo.fromDB(values);
|
|
||||||
assertEquals(1, info.id);
|
|
||||||
assertEquals(1, (long)info.serviceID);
|
|
||||||
assertEquals("http://example.com", info.url);
|
|
||||||
assertTrue(info.readOnly);
|
|
||||||
assertEquals("display name", info.displayName);
|
|
||||||
assertEquals("description", info.description);
|
|
||||||
assertEquals(0xFFFF0000, (int)info.color);
|
|
||||||
assertEquals("tzdata", info.timeZone);
|
|
||||||
assertTrue(info.supportsVEVENT);
|
|
||||||
assertTrue(info.supportsVTODO);
|
|
||||||
assertTrue(info.selected);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -60,6 +60,15 @@
|
|||||||
<action android:name="com.etesync.syncadapter.REINIT_LOGGER"/>
|
<action android:name="com.etesync.syncadapter.REINIT_LOGGER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
<receiver
|
||||||
|
android:name=".App$AppUpdatedReceiver"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||||
|
<data android:scheme="package" android:path="com.etesync.syncadapter" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".AccountSettings$AppUpdatedReceiver"
|
android:name=".AccountSettings$AppUpdatedReceiver"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
@ -8,11 +8,19 @@
|
|||||||
|
|
||||||
package com.etesync.syncadapter;
|
package com.etesync.syncadapter;
|
||||||
|
|
||||||
|
import android.accounts.Account;
|
||||||
|
import android.accounts.AccountManager;
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.Cursor;
|
||||||
|
import android.database.DatabaseUtils;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
@ -27,6 +35,8 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.etesync.syncadapter.log.LogcatHandler;
|
import com.etesync.syncadapter.log.LogcatHandler;
|
||||||
import com.etesync.syncadapter.log.PlainTextFormatter;
|
import com.etesync.syncadapter.log.PlainTextFormatter;
|
||||||
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.Models;
|
import com.etesync.syncadapter.model.Models;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
import com.etesync.syncadapter.model.Settings;
|
import com.etesync.syncadapter.model.Settings;
|
||||||
@ -35,6 +45,8 @@ import org.apache.commons.lang3.time.DateFormatUtils;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.FileHandler;
|
import java.util.logging.FileHandler;
|
||||||
import java.util.logging.Handler;
|
import java.util.logging.Handler;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -207,4 +219,56 @@ public class App extends Application {
|
|||||||
}
|
}
|
||||||
return dataStore;
|
return dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update from previous account settings
|
||||||
|
|
||||||
|
private final static String PREF_VERSION = "version";
|
||||||
|
|
||||||
|
private void update(int fromVersion) {
|
||||||
|
App.log.info("Updating from version " + fromVersion + " to " + BuildConfig.VERSION_CODE);
|
||||||
|
|
||||||
|
if (fromVersion < 6) {
|
||||||
|
EntityDataStore<Persistable> data = this.getData();
|
||||||
|
|
||||||
|
ServiceDB.OpenHelper dbHelper = new ServiceDB.OpenHelper(this);
|
||||||
|
|
||||||
|
List<CollectionInfo> collections = readCollections(dbHelper);
|
||||||
|
for (CollectionInfo info : collections) {
|
||||||
|
JournalEntity journalEntity = new JournalEntity(info);
|
||||||
|
data.insert(journalEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Cleanup SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||||
|
db.delete(ServiceDB.Collections._TABLE, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AppUpdatedReceiver extends BroadcastReceiver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressLint("UnsafeProtectedBroadcastReceiver,MissingPermission")
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
App.log.info("EteSync was updated, checking for app version");
|
||||||
|
|
||||||
|
App app = (App) context.getApplicationContext();
|
||||||
|
SharedPreferences prefs = app.getSharedPreferences("app", Context.MODE_PRIVATE);
|
||||||
|
int fromVersion = prefs.getInt(PREF_VERSION, 1);
|
||||||
|
app.update(fromVersion);
|
||||||
|
prefs.edit().putInt(PREF_VERSION, BuildConfig.VERSION_CODE).apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private List<CollectionInfo> readCollections(ServiceDB.OpenHelper dbHelper) {
|
||||||
|
@Cleanup SQLiteDatabase db = dbHelper.getWritableDatabase();
|
||||||
|
List<CollectionInfo> collections = new LinkedList<>();
|
||||||
|
@Cleanup Cursor cursor = db.query(ServiceDB.Collections._TABLE, null, null, null, null, null, null);
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
DatabaseUtils.cursorRowToContentValues(cursor, values);
|
||||||
|
collections.add(CollectionInfo.fromDB(values));
|
||||||
|
}
|
||||||
|
return collections;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,26 +93,6 @@ public class CollectionInfo implements Serializable {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentValues toDB() {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
// Collections.SERVICE_ID is never changed
|
|
||||||
|
|
||||||
values.put(Collections.URL, url);
|
|
||||||
values.put(Collections.READ_ONLY, readOnly ? 1 : 0);
|
|
||||||
values.put(Collections.DISPLAY_NAME, displayName);
|
|
||||||
values.put(Collections.DESCRIPTION, description);
|
|
||||||
values.put(Collections.COLOR, color);
|
|
||||||
|
|
||||||
values.put(Collections.TIME_ZONE, timeZone);
|
|
||||||
if (supportsVEVENT != null)
|
|
||||||
values.put(Collections.SUPPORTS_VEVENT, supportsVEVENT ? 1 : 0);
|
|
||||||
if (supportsVTODO != null)
|
|
||||||
values.put(Collections.SUPPORTS_VTODO, supportsVTODO ? 1 : 0);
|
|
||||||
|
|
||||||
values.put(Collections.SYNC, selected ? 1 : 0);
|
|
||||||
return values;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CollectionInfo fromJson(String json) {
|
public static CollectionInfo fromJson(String json) {
|
||||||
return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().fromJson(json, CollectionInfo.class);
|
return new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().fromJson(json, CollectionInfo.class);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
package com.etesync.syncadapter.model;
|
package com.etesync.syncadapter.model;
|
||||||
|
|
||||||
import io.requery.CascadeAction;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import io.requery.Column;
|
import io.requery.Column;
|
||||||
|
import io.requery.Convert;
|
||||||
|
import io.requery.Converter;
|
||||||
import io.requery.Entity;
|
import io.requery.Entity;
|
||||||
import io.requery.ForeignKey;
|
import io.requery.ForeignKey;
|
||||||
import io.requery.Generated;
|
import io.requery.Generated;
|
||||||
import io.requery.Index;
|
import io.requery.Index;
|
||||||
import io.requery.Key;
|
import io.requery.Key;
|
||||||
import io.requery.ManyToOne;
|
import io.requery.ManyToOne;
|
||||||
import io.requery.OneToMany;
|
import io.requery.Persistable;
|
||||||
import io.requery.OneToOne;
|
import io.requery.PostLoad;
|
||||||
import io.requery.ReferentialAction;
|
import io.requery.ReferentialAction;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
|
|
||||||
public class JournalModel {
|
public class JournalModel {
|
||||||
@Entity
|
@Entity
|
||||||
@ -21,6 +26,57 @@ public class JournalModel {
|
|||||||
|
|
||||||
@Column(length = 64, unique = true, nullable = false)
|
@Column(length = 64, unique = true, nullable = false)
|
||||||
String uid;
|
String uid;
|
||||||
|
|
||||||
|
@Convert(CollectionInfoConverter.class)
|
||||||
|
CollectionInfo info;
|
||||||
|
|
||||||
|
long service;
|
||||||
|
|
||||||
|
boolean deleted;
|
||||||
|
|
||||||
|
@PostLoad
|
||||||
|
void afterLoad() {
|
||||||
|
this.info.serviceID = service;
|
||||||
|
this.info.url = uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Journal() {
|
||||||
|
this.deleted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Journal(CollectionInfo info) {
|
||||||
|
this();
|
||||||
|
this.info = info;
|
||||||
|
this.uid = info.url;
|
||||||
|
this.service = info.serviceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<CollectionInfo> getCollections(EntityDataStore<Persistable> data, long service) {
|
||||||
|
List<CollectionInfo> ret = new LinkedList<>();
|
||||||
|
|
||||||
|
List<JournalEntity> journals = data.select(JournalEntity.class).where(JournalEntity.SERVICE.eq(service).and(JournalEntity.DELETED.eq(false))).get().toList();
|
||||||
|
for (JournalEntity journal : journals) {
|
||||||
|
// FIXME: For some reason this isn't always being called, manually do it here.
|
||||||
|
journal.afterLoad();
|
||||||
|
ret.add(journal.getInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JournalEntity fetch(EntityDataStore<Persistable> data, String url) {
|
||||||
|
return data.select(JournalEntity.class).where(JournalEntity.UID.eq(url)).limit(1).get().firstOrNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JournalEntity fetchOrCreate(EntityDataStore<Persistable> data, CollectionInfo collection) {
|
||||||
|
JournalEntity journalEntity = fetch(data, collection.url);
|
||||||
|
if (journalEntity == null) {
|
||||||
|
journalEntity = new JournalEntity(collection);
|
||||||
|
} else {
|
||||||
|
journalEntity.setInfo(collection);
|
||||||
|
}
|
||||||
|
return journalEntity;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@ -39,4 +95,31 @@ public class JournalModel {
|
|||||||
@ManyToOne
|
@ManyToOne
|
||||||
Journal journal;
|
Journal journal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class CollectionInfoConverter implements Converter<CollectionInfo, String> {
|
||||||
|
@Override
|
||||||
|
public Class<CollectionInfo> getMappedType() {
|
||||||
|
return CollectionInfo.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<String> getPersistedType() {
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getPersistedSize() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String convertToPersisted(CollectionInfo value) {
|
||||||
|
return value == null ? null : value.toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CollectionInfo convertToMapped(Class<? extends CollectionInfo> type, String value) {
|
||||||
|
return value == null ? null : CollectionInfo.fromJson(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,21 +100,6 @@ public class ServiceDB {
|
|||||||
Services.SERVICE + " TEXT NOT NULL" +
|
Services.SERVICE + " TEXT NOT NULL" +
|
||||||
")");
|
")");
|
||||||
db.execSQL("CREATE UNIQUE INDEX services_account ON " + Services._TABLE + " (" + Services.ACCOUNT_NAME + "," + Services.SERVICE + ")");
|
db.execSQL("CREATE UNIQUE INDEX services_account ON " + Services._TABLE + " (" + Services.ACCOUNT_NAME + "," + Services.SERVICE + ")");
|
||||||
|
|
||||||
db.execSQL("CREATE TABLE " + Collections._TABLE + "(" +
|
|
||||||
Collections.ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
|
|
||||||
Collections.SERVICE_ID + " INTEGER NOT NULL REFERENCES " + Services._TABLE +" ON DELETE CASCADE," +
|
|
||||||
Collections.URL + " TEXT NOT NULL," +
|
|
||||||
Collections.READ_ONLY + " INTEGER DEFAULT 0 NOT NULL," +
|
|
||||||
Collections.DISPLAY_NAME + " TEXT NULL," +
|
|
||||||
Collections.DESCRIPTION + " TEXT NULL," +
|
|
||||||
Collections.COLOR + " INTEGER NULL," +
|
|
||||||
Collections.TIME_ZONE + " TEXT NULL," +
|
|
||||||
Collections.SUPPORTS_VEVENT + " INTEGER NULL," +
|
|
||||||
Collections.SUPPORTS_VTODO + " INTEGER NULL," +
|
|
||||||
Collections.SYNC + " INTEGER DEFAULT 0 NOT NULL" +
|
|
||||||
")");
|
|
||||||
db.execSQL("CREATE UNIQUE INDEX collections_service_url ON " + Collections._TABLE + "(" + Collections.SERVICE_ID + "," + Collections.URL + ")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,21 +11,13 @@ import android.accounts.Account;
|
|||||||
import android.content.AbstractThreadedSyncAdapter;
|
import android.content.AbstractThreadedSyncAdapter;
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SyncResult;
|
import android.content.SyncResult;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.DatabaseUtils;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.database.sqlite.SQLiteException;
|
import android.database.sqlite.SQLiteException;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.provider.CalendarContract;
|
import android.provider.CalendarContract;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings;
|
import com.etesync.syncadapter.AccountSettings;
|
||||||
import com.etesync.syncadapter.App;
|
import com.etesync.syncadapter.App;
|
||||||
@ -34,13 +26,20 @@ import com.etesync.syncadapter.NotificationHelper;
|
|||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Exceptions;
|
import com.etesync.syncadapter.journalmanager.Exceptions;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Collections;
|
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Services;
|
import com.etesync.syncadapter.model.ServiceDB.Services;
|
||||||
import com.etesync.syncadapter.resource.LocalCalendar;
|
import com.etesync.syncadapter.resource.LocalCalendar;
|
||||||
import com.etesync.syncadapter.ui.DebugInfoActivity;
|
import com.etesync.syncadapter.ui.DebugInfoActivity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import at.bitfire.ical4android.CalendarStorageException;
|
import at.bitfire.ical4android.CalendarStorageException;
|
||||||
import lombok.Cleanup;
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
||||||
@ -117,7 +116,12 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
|
|||||||
|
|
||||||
ret = HttpUrl.get(settings.getUri());
|
ret = HttpUrl.get(settings.getUri());
|
||||||
|
|
||||||
Map<String, CollectionInfo> remote = remoteCalendars(db, service);
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
Map<String, CollectionInfo> remote = new HashMap<>();
|
||||||
|
List<CollectionInfo> remoteCollections = JournalEntity.getCollections(data, service);
|
||||||
|
for (CollectionInfo info : remoteCollections) {
|
||||||
|
remote.put(info.url, info);
|
||||||
|
}
|
||||||
|
|
||||||
LocalCalendar[] local = (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null);
|
LocalCalendar[] local = (LocalCalendar[])LocalCalendar.find(account, provider, LocalCalendar.Factory.INSTANCE, null, null);
|
||||||
|
|
||||||
@ -151,23 +155,6 @@ public class CalendarsSyncAdapterService extends SyncAdapterService {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private Map<String, CollectionInfo> remoteCalendars(@NonNull SQLiteDatabase db, Long service) {
|
|
||||||
Map<String, CollectionInfo> collections = new LinkedHashMap<>();
|
|
||||||
if (service != null) {
|
|
||||||
@Cleanup Cursor cursor = db.query(Collections._TABLE, null,
|
|
||||||
Collections.SERVICE_ID + "=? AND " + Collections.SUPPORTS_VEVENT + "!=0 AND " + Collections.SYNC,
|
|
||||||
new String[]{String.valueOf(service)}, null, null, null);
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
DatabaseUtils.cursorRowToContentValues(cursor, values);
|
|
||||||
CollectionInfo info = CollectionInfo.fromDB(values);
|
|
||||||
collections.put(info.url, info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return collections;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,18 +11,11 @@ import android.accounts.Account;
|
|||||||
import android.content.AbstractThreadedSyncAdapter;
|
import android.content.AbstractThreadedSyncAdapter;
|
||||||
import android.content.ContentProviderClient;
|
import android.content.ContentProviderClient;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SyncResult;
|
import android.content.SyncResult;
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.DatabaseUtils;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings;
|
import com.etesync.syncadapter.AccountSettings;
|
||||||
import com.etesync.syncadapter.App;
|
import com.etesync.syncadapter.App;
|
||||||
@ -32,10 +25,14 @@ import com.etesync.syncadapter.NotificationHelper;
|
|||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Exceptions;
|
import com.etesync.syncadapter.journalmanager.Exceptions;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Collections;
|
|
||||||
import com.etesync.syncadapter.ui.DebugInfoActivity;
|
import com.etesync.syncadapter.ui.DebugInfoActivity;
|
||||||
import lombok.Cleanup;
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
||||||
@ -72,7 +69,8 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
|
|||||||
Long service = dbHelper.getService(db, account, ServiceDB.Services.SERVICE_CARDDAV);
|
Long service = dbHelper.getService(db, account, ServiceDB.Services.SERVICE_CARDDAV);
|
||||||
if (service != null) {
|
if (service != null) {
|
||||||
HttpUrl principal = HttpUrl.get(settings.getUri());
|
HttpUrl principal = HttpUrl.get(settings.getUri());
|
||||||
CollectionInfo info = remoteAddressBook(db, service);
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
CollectionInfo info = JournalEntity.getCollections(data, service).get(0);
|
||||||
try {
|
try {
|
||||||
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, settings, extras, authority, provider, syncResult, principal, info);
|
ContactsSyncManager syncManager = new ContactsSyncManager(getContext(), account, settings, extras, authority, provider, syncResult, principal, info);
|
||||||
syncManager.performSync();
|
syncManager.performSync();
|
||||||
@ -103,18 +101,6 @@ public class ContactsSyncAdapterService extends SyncAdapterService {
|
|||||||
|
|
||||||
App.log.info("Address book sync complete");
|
App.log.info("Address book sync complete");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private CollectionInfo remoteAddressBook(@NonNull SQLiteDatabase db, long service) {
|
|
||||||
@Cleanup Cursor c = db.query(Collections._TABLE, null,
|
|
||||||
Collections.SERVICE_ID + "=? AND " + Collections.SYNC, new String[]{String.valueOf(service)}, null, null, null);
|
|
||||||
if (c.moveToNext()) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
DatabaseUtils.cursorRowToContentValues(c, values);
|
|
||||||
return CollectionInfo.fromDB(values);
|
|
||||||
} else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import android.support.annotation.Nullable;
|
|||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.NotificationManagerCompat;
|
import android.support.v4.app.NotificationManagerCompat;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -48,6 +49,7 @@ import com.etesync.syncadapter.journalmanager.Exceptions;
|
|||||||
import com.etesync.syncadapter.journalmanager.JournalManager;
|
import com.etesync.syncadapter.journalmanager.JournalManager;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
import com.etesync.syncadapter.model.JournalEntity;
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
|
import com.etesync.syncadapter.model.JournalModel;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
import com.etesync.syncadapter.ui.PermissionsActivity;
|
import com.etesync.syncadapter.ui.PermissionsActivity;
|
||||||
|
|
||||||
@ -185,35 +187,32 @@ public abstract class SyncAdapterService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private Map<String, CollectionInfo> readCollections(SQLiteDatabase db) {
|
|
||||||
Long service = dbHelper.getService(db, account, serviceType.toString());
|
|
||||||
Map<String, CollectionInfo> collections = new LinkedHashMap<>();
|
|
||||||
@Cleanup Cursor cursor = db.query(ServiceDB.Collections._TABLE, null, ServiceDB.Collections.SERVICE_ID + "=?", new String[]{String.valueOf(service)}, null, null, null);
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
DatabaseUtils.cursorRowToContentValues(cursor, values);
|
|
||||||
collections.put(values.getAsString(ServiceDB.Collections.URL), CollectionInfo.fromDB(values));
|
|
||||||
}
|
|
||||||
return collections;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveCollections(SQLiteDatabase db, Iterable<CollectionInfo> collections) {
|
private void saveCollections(SQLiteDatabase db, Iterable<CollectionInfo> collections) {
|
||||||
EntityDataStore<Persistable> data = ((App) context.getApplicationContext()).getData();
|
|
||||||
Long service = dbHelper.getService(db, account, serviceType.toString());
|
Long service = dbHelper.getService(db, account, serviceType.toString());
|
||||||
db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.SERVICE_ID + "=?", new String[]{String.valueOf(service)});
|
|
||||||
for (CollectionInfo collection : collections) {
|
|
||||||
ContentValues values = collection.toDB();
|
|
||||||
App.log.log(Level.FINE, "Saving collection", values);
|
|
||||||
values.put(ServiceDB.Collections.SERVICE_ID, service);
|
|
||||||
db.insertWithOnConflict(ServiceDB.Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
|
||||||
|
|
||||||
JournalEntity journalEntity = data.select(JournalEntity.class).where(JournalEntity.UID.eq(collection.url)).limit(1).get().firstOrNull();
|
EntityDataStore<Persistable> data = ((App) context.getApplicationContext()).getData();
|
||||||
if (journalEntity == null) {
|
Map<String, CollectionInfo> existing = new HashMap<>();
|
||||||
journalEntity = new JournalEntity();
|
List<CollectionInfo> existingList = JournalEntity.getCollections(data, service);
|
||||||
journalEntity.setUid(collection.url);
|
for (CollectionInfo info : existingList) {
|
||||||
data.insert(journalEntity);
|
existing.put(info.url, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (CollectionInfo collection : collections) {
|
||||||
|
App.log.log(Level.FINE, "Saving collection", collection.url);
|
||||||
|
|
||||||
|
collection.serviceID = service;
|
||||||
|
JournalEntity journalEntity = JournalEntity.fetchOrCreate(data, collection);
|
||||||
|
data.upsert(journalEntity);
|
||||||
|
|
||||||
|
existing.remove(collection.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (CollectionInfo collection : existing.values()) {
|
||||||
|
App.log.log(Level.FINE, "Deleting collection", collection.url);
|
||||||
|
|
||||||
|
JournalEntity journalEntity = data.select(JournalEntity.class).where(JournalEntity.UID.eq(collection.url)).limit(1).get().first();
|
||||||
|
journalEntity.setDeleted(true);
|
||||||
|
data.update(journalEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import android.app.LoaderManager;
|
|||||||
import android.content.AsyncTaskLoader;
|
import android.content.AsyncTaskLoader;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -26,7 +25,6 @@ import android.content.Loader;
|
|||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.SyncStatusObserver;
|
import android.content.SyncStatusObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.DatabaseUtils;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -34,7 +32,6 @@ import android.os.Bundle;
|
|||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.provider.CalendarContract;
|
import android.provider.CalendarContract;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
@ -64,11 +61,13 @@ import com.etesync.syncadapter.App;
|
|||||||
import com.etesync.syncadapter.Constants;
|
import com.etesync.syncadapter.Constants;
|
||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Collections;
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB.OpenHelper;
|
import com.etesync.syncadapter.model.ServiceDB.OpenHelper;
|
||||||
import com.etesync.syncadapter.model.ServiceDB.Services;
|
import com.etesync.syncadapter.model.ServiceDB.Services;
|
||||||
import com.etesync.syncadapter.resource.LocalCalendar;
|
import com.etesync.syncadapter.resource.LocalCalendar;
|
||||||
import at.bitfire.ical4android.TaskProvider;
|
import at.bitfire.ical4android.TaskProvider;
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
|
|
||||||
import static android.content.ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
|
import static android.content.ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE;
|
||||||
@ -331,6 +330,7 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
|||||||
|
|
||||||
@Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
|
@Cleanup OpenHelper dbHelper = new OpenHelper(getContext());
|
||||||
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
SQLiteDatabase db = dbHelper.getReadableDatabase();
|
||||||
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
|
||||||
@Cleanup Cursor cursor = db.query(
|
@Cleanup Cursor cursor = db.query(
|
||||||
Services._TABLE,
|
Services._TABLE,
|
||||||
@ -345,32 +345,18 @@ public class AccountActivity extends AppCompatActivity implements Toolbar.OnMenu
|
|||||||
info.carddav = new AccountInfo.ServiceInfo();
|
info.carddav = new AccountInfo.ServiceInfo();
|
||||||
info.carddav.id = id;
|
info.carddav.id = id;
|
||||||
info.carddav.refreshing = (davService != null && davService.isRefreshing(id)) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
|
info.carddav.refreshing = (davService != null && davService.isRefreshing(id)) || ContentResolver.isSyncActive(account, ContactsContract.AUTHORITY);
|
||||||
info.carddav.collections = readCollections(db, id);
|
info.carddav.collections = JournalEntity.getCollections(data, id);
|
||||||
|
|
||||||
} else if (Services.SERVICE_CALDAV.equals(service)) {
|
} else if (Services.SERVICE_CALDAV.equals(service)) {
|
||||||
info.caldav = new AccountInfo.ServiceInfo();
|
info.caldav = new AccountInfo.ServiceInfo();
|
||||||
info.caldav.id = id;
|
info.caldav.id = id;
|
||||||
info.caldav.refreshing = (davService != null && davService.isRefreshing(id)) ||
|
info.caldav.refreshing = (davService != null && davService.isRefreshing(id)) ||
|
||||||
ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) ||
|
ContentResolver.isSyncActive(account, CalendarContract.AUTHORITY) ||
|
||||||
ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority);
|
ContentResolver.isSyncActive(account, TaskProvider.ProviderName.OpenTasks.authority);
|
||||||
info.caldav.collections = readCollections(db, id);
|
info.caldav.collections = JournalEntity.getCollections(data, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<CollectionInfo> readCollections(@NonNull SQLiteDatabase db, long service) {
|
|
||||||
List<CollectionInfo> collections = new LinkedList<>();
|
|
||||||
@Cleanup Cursor cursor = db.query(Collections._TABLE, null, Collections.SERVICE_ID + "=?",
|
|
||||||
new String[] { String.valueOf(service) }, null, null, Collections.SUPPORTS_VEVENT + " DESC," + Collections.DISPLAY_NAME);
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
ContentValues values = new ContentValues();
|
|
||||||
DatabaseUtils.cursorRowToContentValues(cursor, values);
|
|
||||||
collections.add(CollectionInfo.fromDB(values));
|
|
||||||
}
|
|
||||||
return collections;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,13 +27,18 @@ import android.support.v4.content.AsyncTaskLoader;
|
|||||||
import android.support.v4.content.Loader;
|
import android.support.v4.content.Loader;
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings;
|
import com.etesync.syncadapter.AccountSettings;
|
||||||
|
import com.etesync.syncadapter.App;
|
||||||
import com.etesync.syncadapter.HttpClient;
|
import com.etesync.syncadapter.HttpClient;
|
||||||
import com.etesync.syncadapter.InvalidAccountException;
|
import com.etesync.syncadapter.InvalidAccountException;
|
||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Exceptions;
|
import com.etesync.syncadapter.journalmanager.Exceptions;
|
||||||
import com.etesync.syncadapter.journalmanager.JournalManager;
|
import com.etesync.syncadapter.journalmanager.JournalManager;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
|
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
@ -161,9 +166,11 @@ public class CreateCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. add collection to service
|
// 2. add collection to service
|
||||||
ContentValues values = info.toDB();
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
|
info.serviceID = serviceID;
|
||||||
db.insertWithOnConflict(ServiceDB.Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
JournalEntity journalEntity = JournalEntity.fetchOrCreate(data, info);
|
||||||
|
data.upsert(journalEntity);
|
||||||
|
|
||||||
|
|
||||||
requestSync(authority);
|
requestSync(authority);
|
||||||
} catch (IllegalStateException | Exceptions.HttpException e) {
|
} catch (IllegalStateException | Exceptions.HttpException e) {
|
||||||
|
@ -36,6 +36,7 @@ import java.io.File;
|
|||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings;
|
import com.etesync.syncadapter.AccountSettings;
|
||||||
@ -45,7 +46,11 @@ import com.etesync.syncadapter.Constants;
|
|||||||
import com.etesync.syncadapter.InvalidAccountException;
|
import com.etesync.syncadapter.InvalidAccountException;
|
||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Exceptions.HttpException;
|
import com.etesync.syncadapter.journalmanager.Exceptions.HttpException;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
|
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
|
|
||||||
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
|
||||||
@ -240,6 +245,14 @@ public class DebugInfoActivity extends AppCompatActivity implements LoaderManage
|
|||||||
dbHelper.dump(report);
|
dbHelper.dump(report);
|
||||||
report.append("\n");
|
report.append("\n");
|
||||||
|
|
||||||
|
report.append("JOURNALS DUMP\n");
|
||||||
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
List<JournalEntity> journals = data.select(JournalEntity.class).where(JournalEntity.DELETED.eq(false)).get().toList();
|
||||||
|
for (JournalEntity journal : journals) {
|
||||||
|
report.append(journal.toString() + "\n");
|
||||||
|
}
|
||||||
|
report.append("\n");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
report.append(
|
report.append(
|
||||||
"SYSTEM INFORMATION\n" +
|
"SYSTEM INFORMATION\n" +
|
||||||
|
@ -14,7 +14,6 @@ import android.app.Dialog;
|
|||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
@ -25,13 +24,17 @@ import android.support.v7.app.AlertDialog;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.etesync.syncadapter.AccountSettings;
|
import com.etesync.syncadapter.AccountSettings;
|
||||||
|
import com.etesync.syncadapter.App;
|
||||||
import com.etesync.syncadapter.HttpClient;
|
import com.etesync.syncadapter.HttpClient;
|
||||||
import com.etesync.syncadapter.InvalidAccountException;
|
import com.etesync.syncadapter.InvalidAccountException;
|
||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Exceptions;
|
import com.etesync.syncadapter.journalmanager.Exceptions;
|
||||||
import com.etesync.syncadapter.journalmanager.JournalManager;
|
import com.etesync.syncadapter.journalmanager.JournalManager;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
|
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
|
|
||||||
public class DeleteCollectionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Exception> {
|
public class DeleteCollectionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Exception> {
|
||||||
@ -94,13 +97,11 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
protected static class DeleteCollectionLoader extends AsyncTaskLoader<Exception> {
|
protected static class DeleteCollectionLoader extends AsyncTaskLoader<Exception> {
|
||||||
final Account account;
|
final Account account;
|
||||||
final CollectionInfo collectionInfo;
|
final CollectionInfo collectionInfo;
|
||||||
final ServiceDB.OpenHelper dbHelper;
|
|
||||||
|
|
||||||
public DeleteCollectionLoader(Context context, Account account, CollectionInfo collectionInfo) {
|
public DeleteCollectionLoader(Context context, Account account, CollectionInfo collectionInfo) {
|
||||||
super(context);
|
super(context);
|
||||||
this.account = account;
|
this.account = account;
|
||||||
this.collectionInfo = collectionInfo;
|
this.collectionInfo = collectionInfo;
|
||||||
dbHelper = new ServiceDB.OpenHelper(getContext());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,23 +113,20 @@ public class DeleteCollectionFragment extends DialogFragment implements LoaderMa
|
|||||||
public Exception loadInBackground() {
|
public Exception loadInBackground() {
|
||||||
try {
|
try {
|
||||||
// delete collection locally
|
// delete collection locally
|
||||||
SQLiteDatabase db = dbHelper.getWritableDatabase();
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
|
||||||
AccountSettings settings = new AccountSettings(getContext(), account);
|
AccountSettings settings = new AccountSettings(getContext(), account);
|
||||||
HttpUrl principal = HttpUrl.get(settings.getUri());
|
HttpUrl principal = HttpUrl.get(settings.getUri());
|
||||||
|
|
||||||
JournalManager journalManager = new JournalManager(HttpClient.create(getContext(), account), principal);
|
JournalManager journalManager = new JournalManager(HttpClient.create(getContext(), account), principal);
|
||||||
journalManager.deleteJournal(new JournalManager.Journal(settings.password(), collectionInfo.toJson(), collectionInfo.url));
|
journalManager.deleteJournal(new JournalManager.Journal(settings.password(), collectionInfo.toJson(), collectionInfo.url));
|
||||||
|
data.delete(JournalEntity.fetch(data, collectionInfo.url));
|
||||||
db.delete(ServiceDB.Collections._TABLE, ServiceDB.Collections.ID + "=?", new String[]{String.valueOf(collectionInfo.id)});
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (Exceptions.HttpException e) {
|
} catch (Exceptions.HttpException e) {
|
||||||
return e;
|
return e;
|
||||||
} catch (InvalidAccountException e) {
|
} catch (InvalidAccountException e) {
|
||||||
return e;
|
return e;
|
||||||
} finally {
|
|
||||||
dbHelper.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,13 @@ import com.etesync.syncadapter.InvalidAccountException;
|
|||||||
import com.etesync.syncadapter.R;
|
import com.etesync.syncadapter.R;
|
||||||
import com.etesync.syncadapter.journalmanager.Helpers;
|
import com.etesync.syncadapter.journalmanager.Helpers;
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
import com.etesync.syncadapter.model.CollectionInfo;
|
||||||
|
import com.etesync.syncadapter.model.JournalEntity;
|
||||||
import com.etesync.syncadapter.model.ServiceDB;
|
import com.etesync.syncadapter.model.ServiceDB;
|
||||||
import com.etesync.syncadapter.resource.LocalTaskList;
|
import com.etesync.syncadapter.resource.LocalTaskList;
|
||||||
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration;
|
import com.etesync.syncadapter.ui.setup.BaseConfigurationFinder.Configuration;
|
||||||
import at.bitfire.ical4android.TaskProvider;
|
import at.bitfire.ical4android.TaskProvider;
|
||||||
|
import io.requery.Persistable;
|
||||||
|
import io.requery.sql.EntityDataStore;
|
||||||
import lombok.Cleanup;
|
import lombok.Cleanup;
|
||||||
|
|
||||||
public class SetupEncryptionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Configuration> {
|
public class SetupEncryptionFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Configuration> {
|
||||||
@ -176,12 +179,13 @@ public class SetupEncryptionFragment extends DialogFragment implements LoaderMan
|
|||||||
values.put(ServiceDB.Services.ACCOUNT_NAME, accountName);
|
values.put(ServiceDB.Services.ACCOUNT_NAME, accountName);
|
||||||
values.put(ServiceDB.Services.SERVICE, service);
|
values.put(ServiceDB.Services.SERVICE, service);
|
||||||
long serviceID = db.insertWithOnConflict(ServiceDB.Services._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
long serviceID = db.insertWithOnConflict(ServiceDB.Services._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||||
|
EntityDataStore<Persistable> data = ((App) getContext().getApplicationContext()).getData();
|
||||||
|
|
||||||
// insert collections
|
// insert collections
|
||||||
for (CollectionInfo collection : info.collections.values()) {
|
for (CollectionInfo collection : info.collections.values()) {
|
||||||
values = collection.toDB();
|
collection.serviceID = serviceID;
|
||||||
values.put(ServiceDB.Collections.SERVICE_ID, serviceID);
|
JournalEntity journalEntity = new JournalEntity(collection);
|
||||||
db.insertWithOnConflict(ServiceDB.Collections._TABLE, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
data.insert(journalEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviceID;
|
return serviceID;
|
||||||
|
Loading…
Reference in New Issue
Block a user