Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Offline Support #454

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ uploadArchives {

pom.whenConfigured {
p -> p.dependencies = p.dependencies.findAll {
dep -> ( dep.artifactId != "commons" && dep.artifactId != "weborbclient" )
dep -> ( dep.artifactId != "commons" &&
dep.artifactId != "weborbclient" &&
dep.artifactId != "antlr4-runtime" )
}
}

Expand Down Expand Up @@ -181,7 +183,8 @@ def libsToPackage() {
def artifactsToPackage =
[
["com.backendless", "commons"],
["weborb", "weborbclient"]
["weborb", "weborbclient"],
["org.antlr", "antlr4-runtime"]
]

def libsToPackage = ["mediaLib.jar"]
Expand Down Expand Up @@ -263,10 +266,13 @@ dependencies {
}
compileOnly( group: "weborb", name: "weborbclient", version: "5.1.0.212", changing: true)

compileOnly( group: 'org.antlr', name: 'antlr4-runtime', version: '4.7.2', changing: true)

compileOnly ('io.socket:socket.io-client:1.0.0') {
// excluding org.json which is provided by Android
exclude group: 'org.json', module: 'json'
}

}

apply plugin: 'java'
115 changes: 110 additions & 5 deletions src/com/backendless/DataStoreFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
import com.backendless.persistence.BackendlessSerializer;
import com.backendless.persistence.DataQueryBuilder;
import com.backendless.persistence.LoadRelationsQueryBuilder;
import com.backendless.persistence.offline.LocalStorageManager;
import com.backendless.persistence.offline.OfflineAwareCallback;
import com.backendless.persistence.offline.SyncCompletionCallback;
import com.backendless.persistence.offline.SyncManager;
import com.backendless.persistence.offline.TransactionManager;
import com.backendless.rt.data.EventHandler;
import com.backendless.rt.data.EventHandlerFactory;

Expand All @@ -33,17 +38,23 @@
import java.util.List;
import java.util.Map;

import static com.backendless.persistence.BackendlessSerializer.serializeToMap;

class DataStoreFactory
{
private static final List<String> emptyRelations = new ArrayList<String>();
private final static EventHandlerFactory eventHandlerFactory = new EventHandlerFactory();
private static final EventHandlerFactory eventHandlerFactory = new EventHandlerFactory();
private static final TransactionManager transactionManager = TransactionManager.getInstance();
private static final SyncManager syncManager = SyncManager.getInstance();

protected static <E> IDataStore<E> createDataStore( final Class<E> entityClass )
{

return new IDataStore<E>()
{
private EventHandler<E> eventHandler = eventHandlerFactory.of( entityClass );
private final LocalStorageManager storageManager = new LocalStorageManager(
BackendlessSerializer.getSimpleName( entityClass ));

@Override
public List<String> create( List<E> objects ) throws BackendlessException
Expand Down Expand Up @@ -215,25 +226,37 @@ public void findLast( List<String> relations, Integer relationsDepth, Integer re
@Override
public List<E> find() throws BackendlessException
{
return Backendless.Persistence.find( entityClass, DataQueryBuilder.create() );
return find(DataQueryBuilder.create() );
}

@Override
public List<E> find( DataQueryBuilder dataQueryBuilder ) throws BackendlessException
{
return Backendless.Persistence.find( entityClass, dataQueryBuilder );
if (!storageManager.shouldRetrieveOnline(dataQueryBuilder))
return storageManager.find(entityClass, dataQueryBuilder);

List<E> result = Backendless.Persistence.find( entityClass, dataQueryBuilder );
storageManager.store(result, dataQueryBuilder);
return result;
}

@Override
public void find( AsyncCallback<List<E>> responder )
{
Backendless.Persistence.find( entityClass, DataQueryBuilder.create(), responder );
find(DataQueryBuilder.create(), responder );
}

@Override
public void find( DataQueryBuilder dataQueryBuilder, AsyncCallback<List<E>> responder )
{
Backendless.Persistence.find( entityClass, dataQueryBuilder, responder );
if (!storageManager.shouldRetrieveOnline(dataQueryBuilder)) {
storageManager.find(entityClass, dataQueryBuilder, responder);
return;
}

AsyncCallback<List<E>> storeCallback = storageManager.getStoreCallback(dataQueryBuilder, responder);

Backendless.Persistence.find( entityClass, dataQueryBuilder, storeCallback );
}

@Override
Expand Down Expand Up @@ -639,6 +662,88 @@ public EventHandler<E> rt()
{
return eventHandler;
}

/*
TODO: OFFLINE SECTION
*/

@Override
public void initLocalDatabase(String whereClause, AsyncCallback<Integer> responder) {
storageManager.initDatabase(whereClause, responder);
}

@Override
public void clearLocalDatabase() {
storageManager.clearLocalDatabase();
}

@Override
public void saveEventually(E entity) {
saveEventually(entity, null);
}

@Override
public void saveEventually(E entity, OfflineAwareCallback<E> responder) {
int blLocalId = storageManager.save(entity, responder);
Map serializedEntity = serializeToMap( entity );
serializedEntity.put("blLocalId", blLocalId);

Object[] args = new Object[] {
BackendlessSerializer.getSimpleName( entity.getClass() ),
serializedEntity};

transactionManager.scheduleOperation("save", args, entityClass.getName(), responder);
}

@Override
public void removeEventually(E entity) {
removeEventually(entity, null);
}

@Override
public void removeEventually(E entity, OfflineAwareCallback<E> responder) {
final Map<String, Object> serializedEntity = serializeToMap( entity );

Object[] args = new Object[] {
BackendlessSerializer.getSimpleName( entity.getClass() ),
serializedEntity };

transactionManager.scheduleOperation("remove", args, entityClass.getName(), responder);
}

@Override
public void onSave(AsyncCallback<E> responder) {
transactionManager.onSave(BackendlessSerializer.getSimpleName( entityClass ), responder);

}

@Override
public void onRemove(AsyncCallback<E> responder) {
transactionManager.onRemove(BackendlessSerializer.getSimpleName( entityClass ), responder);

}

@Override
public void enableAutoSync() {
syncManager.enableAutoSync(BackendlessSerializer.getSimpleName( entityClass ));
}

@Override
public void disableAutoSync() {
syncManager.disableAutoSync(BackendlessSerializer.getSimpleName( entityClass ));
}

@Override
public boolean isAutoSyncEnabled() {
return syncManager.isAutoSyncEnabled(BackendlessSerializer.getSimpleName( entityClass ));
}

@Override
public void startOfflineSync(SyncCompletionCallback callback) {
syncManager.startSemiAutoSynchronization(BackendlessSerializer.getSimpleName( entityClass ), callback);
}


};
}
}
26 changes: 26 additions & 0 deletions src/com/backendless/IDataStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@
package com.backendless;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.backendless.async.callback.AsyncCallback;
import com.backendless.exceptions.BackendlessException;
import com.backendless.persistence.DataQueryBuilder;
import com.backendless.persistence.LoadRelationsQueryBuilder;
import com.backendless.persistence.offline.OfflineAwareCallback;
import com.backendless.persistence.offline.SyncCompletionCallback;
import com.backendless.rt.data.EventHandler;

import java.util.Collection;
Expand Down Expand Up @@ -206,4 +209,27 @@ public interface IDataStore<E>
void deleteRelation( @NonNull String parentObjectId, @NonNull String relationColumnName, @NonNull String whereClause, AsyncCallback<Integer> callback );

EventHandler<E> rt();

/*
TODO: OFFLINE SECTION
*/

void initLocalDatabase(@Nullable String whereClause, AsyncCallback<Integer> responder);

void clearLocalDatabase();

void saveEventually(E entity);
void saveEventually(E entity, OfflineAwareCallback<E> responder );

void removeEventually(E entity);
void removeEventually(E entity, OfflineAwareCallback<E> responder );

void onSave(AsyncCallback<E> responder);
void onRemove(AsyncCallback<E> responder);

void enableAutoSync();
void disableAutoSync();
boolean isAutoSyncEnabled();

void startOfflineSync(SyncCompletionCallback responder);
}
51 changes: 50 additions & 1 deletion src/com/backendless/Persistence.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
import com.backendless.persistence.LoadRelationsQueryBuilder;
import com.backendless.persistence.MapDrivenDataStore;
import com.backendless.persistence.QueryOptions;
import com.backendless.persistence.offline.DataRetrievalPolicy;
import com.backendless.persistence.offline.DatabaseManager;
import com.backendless.persistence.offline.LocalStoragePolicy;
import com.backendless.persistence.offline.SQLiteDatabaseManager;
import com.backendless.persistence.offline.SyncCompletionCallback;
import com.backendless.persistence.offline.SyncManager;
import com.backendless.property.ObjectProperty;
import com.backendless.utils.MapEntityUtil;
import com.backendless.utils.ReflectionUtil;
Expand All @@ -50,6 +56,9 @@
import java.util.List;
import java.util.Map;

import static com.backendless.persistence.offline.DataRetrievalPolicy.*;
import static com.backendless.persistence.offline.LocalStoragePolicy.DONOTSTOREANY;

public final class Persistence
{
public final static String PERSISTENCE_MANAGER_SERVER_ALIAS = "com.backendless.services.persistence.PersistenceService";
Expand All @@ -67,6 +76,18 @@ public final class Persistence

private static final Persistence instance = new Persistence();


/*
TODO: OFFLINE SECTION
*/

private final DatabaseManager databaseManager;
private final SyncManager syncManager;

public DataRetrievalPolicy RetrievalPolicy = ONLINEONLY;
public LocalStoragePolicy LocalStoragePolicy = DONOTSTOREANY;


static Persistence getInstance()
{
return instance;
Expand All @@ -77,6 +98,10 @@ private Persistence()
Types.addClientClassMapping( "com.backendless.services.persistence.BackendlessDataQuery", BackendlessDataQuery.class );
Types.addClientClassMapping( "com.backendless.services.persistence.ObjectProperty", ObjectProperty.class );
Types.addClientClassMapping( "com.backendless.services.persistence.QueryOptions", QueryOptions.class );

databaseManager = SQLiteDatabaseManager.getInstance();
syncManager = SyncManager.getInstance();
syncManager.startAutoSynchronization();
}

public void mapTableToClass( String tableName, Class clazz )
Expand Down Expand Up @@ -965,7 +990,7 @@ public void callStoredProcedure( String procedureName, Map<String, Object> argum
Invoker.invokeAsync( PERSISTENCE_MANAGER_SERVER_ALIAS, "callStoredProcedure", args, responder, ResponderHelper.getCollectionAdaptingResponder( HashMap.class ) );
}

private <E> Map<String, Object> serializeEntityBeforeCreate( final E entity )
<E> Map<String, Object> serializeEntityBeforeCreate( final E entity )
{
if( entity == null )
throw new IllegalArgumentException( ExceptionMessage.NULL_ENTITY );
Expand All @@ -988,4 +1013,28 @@ public Object substitute( Object o )

return serializedEntity;
}

/*
TODO: OFFLINE SECTION
*/

public void clearLocalDatabase() {
databaseManager.resetDatabase();
}

public void enableAutoSync() {
syncManager.enableAutoSync();
}

public void disableAutoSync() {
syncManager.disableAutoSync();
}

public boolean isAutoSyncEnabled() {
return syncManager.isAutoSyncEnabled();
}

public void startOfflineSync(SyncCompletionCallback callback) {
syncManager.startSemiAutoSynchronization(callback);
}
}
23 changes: 23 additions & 0 deletions src/com/backendless/persistence/DataQueryBuilder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.backendless.persistence;

import com.backendless.persistence.offline.DataRetrievalPolicy;
import com.backendless.persistence.offline.LocalStoragePolicy;

import java.util.ArrayList;
import java.util.List;

Expand All @@ -13,6 +16,8 @@ public class DataQueryBuilder
private String whereClause;
private List<String> groupBy;
private String havingClause;
private DataRetrievalPolicy retrievalPolicy;
private LocalStoragePolicy storagePolicy;

private DataQueryBuilder()
{
Expand Down Expand Up @@ -255,4 +260,22 @@ public Integer getRelationPageSize()
{
return queryOptionsBuilder.getRelationsPageSize();
}

public DataQueryBuilder setRetrievalPolicy(DataRetrievalPolicy retrievalPolicy) {
this.retrievalPolicy = retrievalPolicy;
return this;
}

public DataRetrievalPolicy getRetrievalPolicy() {
return retrievalPolicy;
}

public LocalStoragePolicy getStoragePolicy() {
return storagePolicy;
}

public DataQueryBuilder setStoragePolicy(LocalStoragePolicy storagePolicy) {
this.storagePolicy = storagePolicy;
return this;
}
}
Loading