Exemplo n.º 1
0
 public SynchronizationThread(NoteRepository repository, ISynchronizationFeedback[] synclistener, ConflictResolutionStrategyConfig strat, IAlephDispatcher disp)
 {
     repo             = repository;
     listener         = synclistener.ToList();
     conflictStrategy = ConflictResolutionStrategyHelper.ToInterfaceType(strat);
     dispatcher       = disp;
     _comChannel      = new ManualResetEvent(false);
 }
Exemplo n.º 2
0
        public void OpenWithAutomaticConflictResolution(string filename, DataSource source,
                                                        ConflictResolutionStrategy resolutionStrategy,
                                                        Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback)
        {
            Misc.CheckNotNull(filename);
            Misc.CheckNotNull(completedCallback);
            var prefetchDataOnConflict        = false;
            ConflictCallback conflictCallback = null;

            completedCallback = ToOnGameThread(completedCallback);

            if (conflictCallback == null)
            {
                conflictCallback = (resolver, original, originalData, unmerged, unmergedData) =>
                {
                    switch (resolutionStrategy)
                    {
                    case ConflictResolutionStrategy.UseOriginal:
                        resolver.ChooseMetadata(original);
                        return;

                    case ConflictResolutionStrategy.UseUnmerged:
                        resolver.ChooseMetadata(unmerged);
                        return;

                    case ConflictResolutionStrategy.UseLongestPlaytime:
                        if (original.TotalTimePlayed >= unmerged.TotalTimePlayed)
                        {
                            resolver.ChooseMetadata(original);
                        }
                        else
                        {
                            resolver.ChooseMetadata(unmerged);
                        }

                        return;

                    default:
                        Logger.e("Unhandled strategy " + resolutionStrategy);
                        completedCallback(SavedGameRequestStatus.InternalError, null);
                        return;
                    }
                }
            }
            ;

            conflictCallback = ToOnGameThread(conflictCallback);

            if (!IsValidFilename(filename))
            {
                Logger.e("Received invalid filename: " + filename);
                completedCallback(SavedGameRequestStatus.BadInputError, null);
                return;
            }

            InternalOpen(filename, source, resolutionStrategy, prefetchDataOnConflict, conflictCallback,
                         completedCallback);
        }
Exemplo n.º 3
0
        public HttpResponseMessage ResolveConflict(string filename, ConflictResolutionStrategy strategy)
        {
            var canonicalFilename = FileHeader.Canonize(filename);

            if (Log.IsDebugEnabled)
            {
                Log.Debug("Resolving conflict of a file '{0}' by using {1} strategy", filename, strategy);
            }

            switch (strategy)
            {
            case ConflictResolutionStrategy.CurrentVersion:

                Storage.Batch(accessor =>
                {
                    var localMetadata = accessor.GetFile(canonicalFilename, 0, 0).Metadata;
                    var conflict      = accessor.GetConfigurationValue <ConflictItem>(RavenFileNameHelper.ConflictConfigNameForFile(canonicalFilename));

                    ConflictResolver.ApplyCurrentStrategy(canonicalFilename, conflict, localMetadata);

                    accessor.UpdateFileMetadata(canonicalFilename, localMetadata, null);

                    ConflictArtifactManager.Delete(canonicalFilename, accessor);
                });

                Publisher.Publish(new ConflictNotification
                {
                    FileName = canonicalFilename,
                    Status   = ConflictStatus.Resolved
                });

                break;

            case ConflictResolutionStrategy.RemoteVersion:

                Storage.Batch(accessor =>
                {
                    var localMetadata = accessor.GetFile(canonicalFilename, 0, 0).Metadata;
                    var conflict      = accessor.GetConfig(RavenFileNameHelper.ConflictConfigNameForFile(canonicalFilename)).JsonDeserialization <ConflictItem>();

                    ConflictResolver.ApplyRemoteStrategy(canonicalFilename, conflict, localMetadata);

                    accessor.UpdateFileMetadata(canonicalFilename, localMetadata, null);
                    accessor.SetConfig(RavenFileNameHelper.ConflictConfigNameForFile(canonicalFilename), JsonExtensions.ToJObject(conflict));

                    // ConflictArtifactManager.Delete(canonicalFilename, accessor); - intentionally not deleting, conflict item will be removed when a remote file is put
                });

                SynchronizationTask.Context.NotifyAboutWork();

                break;

            default:
                throw new NotSupportedException(string.Format("{0} is not the valid strategy to resolve a conflict", strategy));
            }

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!IsOpen)
            {
                Open(Path);
            }
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet     = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index        = 0;

            var args = new object[valueSet.Count];

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.Append("?");

                args[index] = column.Value;

                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var          sql = builder.ToString();
            sqlite3_stmt command;

            lock (dbLock) {
                command = db.prepare(sql);
                command.bind(args);
            }

            return(command);
        }
		public override bool TryResolve(string fileName, RavenJObject localMedatada, RavenJObject remoteMetadata, out ConflictResolutionStrategy resolutionStrategy)
		{
			var remoteFileLastModified = GetLastModified(remoteMetadata);
			var localFileLastModified = GetLastModified(localMedatada);

			if (remoteFileLastModified > localFileLastModified)
				resolutionStrategy = ConflictResolutionStrategy.RemoteVersion;
			else
				resolutionStrategy = ConflictResolutionStrategy.CurrentVersion;

			return true;
		}
Exemplo n.º 6
0
        public void OpenWithAutomaticConflictResolution(string filename, DataSource source,
                                                        ConflictResolutionStrategy resolutionStrategy,
                                                        Action <SavedGameRequestStatus, ISavedGameMetadata> callback)
        {
            bubble.CheckNotNull(filename);
            bubble.CheckNotNull(callback);

            callback = ToOnGameThread(callback);

            if (!IsValidFilename(filename))
            {
                Logger.e("Received invalid filename: " + filename);
                callback(SavedGameRequestStatus.BadInputError, null);
                return;
            }

            OpenWithManualConflictResolution(
                filename, source, false,
                (resolver, original, originalData, unmerged, unmergedData) =>
            {
                switch (resolutionStrategy)
                {
                case ConflictResolutionStrategy.UseOriginal:
                    resolver.ChooseMetadata(original);
                    return;

                case ConflictResolutionStrategy.UseUnmerged:
                    resolver.ChooseMetadata(unmerged);
                    return;

                case ConflictResolutionStrategy.UseLongestPlaytime:
                    if (original.TotalTimePlayed >= unmerged.TotalTimePlayed)
                    {
                        resolver.ChooseMetadata(original);
                    }
                    else
                    {
                        resolver.ChooseMetadata(unmerged);
                    }
                    return;

                default:
                    Logger.e("Unhandled strategy " + resolutionStrategy);
                    callback(SavedGameRequestStatus.InternalError, null);
                    return;
                }
            },
                callback
                );
        }
        public HttpResponseMessage ResolveConflict(string fileName, ConflictResolutionStrategy strategy)
        {
            Log.Debug("Resolving conflict of a file '{0}' by using {1} strategy", fileName, strategy);

            if (strategy == ConflictResolutionStrategy.CurrentVersion)
            {
                StrategyAsGetCurrent(fileName);
            }
            else
            {
                StrategyAsGetRemote(fileName);
            }

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
Exemplo n.º 8
0
        private static Types.SnapshotConflictPolicy AsConflictPolicy(ConflictResolutionStrategy strategy)
        {
            switch (strategy)
            {
            case ConflictResolutionStrategy.UseLongestPlaytime:
                return(Types.SnapshotConflictPolicy.LONGEST_PLAYTIME);

            case ConflictResolutionStrategy.UseOriginal:
                return(Types.SnapshotConflictPolicy.LAST_KNOWN_GOOD);

            case ConflictResolutionStrategy.UseUnmerged:
                return(Types.SnapshotConflictPolicy.MOST_RECENTLY_MODIFIED);
            }
            throw new InvalidOperationException("Found unhandled strategy: " + strategy);
        }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        ISQLiteStatement GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet     = values.ValueSet();
            var sqlParams    = new Dictionary <string, object> ();
            var valueBuilder = new StringBuilder();
            var index        = 0L;

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.AppendFormat("@{0}", column.Key);

                index++;
                sqlParams.Add(column.Key, column.Value);
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var stmt = connection.Prepare(builder.ToString());

            foreach (var p in sqlParams)
            {
                stmt.Bind(p.Key, p.Value);
            }

            return(stmt);
        }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet     = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index        = 0;

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.Append("@");
                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql     = builder.ToString();
            var command = Connection.Prepare(sql);

            index = 1;
            foreach (var val in valueSet)
            {
                var key = val.Key;
                command.Bind(index++, values[key]);
            }

            return(command);
        }
Exemplo n.º 11
0
        public async Task ResolveConflictsAsync(ConflictResolutionStrategy strategy)
        {
            var requestUriString = string.Format("{0}/synchronization/resolveConflicts?strategy={1}",
                                                 baseUrl, Uri.EscapeDataString(strategy.ToString()));

            using (var request = RequestFactory.CreateHttpJsonRequest(new CreateHttpJsonRequestParams(this, requestUriString, HttpMethods.Patch, Credentials, Conventions)).AddOperationHeaders(OperationsHeaders))
            {
                try
                {
                    await request.ExecuteRequestAsync().ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    throw e.SimplifyException();
                }
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        SqliteCommand GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet     = values.ValueSet();
            var sqlParams    = new SqliteParameter[valueSet.LongCount()];
            var valueBuilder = new StringBuilder();
            var index        = 0L;

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.AppendFormat("@{0}", column.Key);

                sqlParams[index++] = new SqliteParameter(column.Key, column.Value);
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql     = builder.ToString();
            var command = new SqliteCommand(sql, Connection, currentTransaction);

            command.Parameters.Clear();
            command.Parameters.AddRange(sqlParams);

            return(command);
        }
Exemplo n.º 13
0
        public HttpResponseMessage ResolveConflicts(ConflictResolutionStrategy strategy)
        {
            IList <ConflictItem> conflicts = null;

            Storage.Batch(accessor =>
            {
                int totalCount;
                var values = accessor.GetConfigsStartWithPrefix(RavenFileNameHelper.ConflictConfigNamePrefix, 0, int.MaxValue, out totalCount);
                conflicts  = values.Select(x => JsonExtensions.JsonDeserialization <ConflictItem>(x)).ToList();
            });

            foreach (var conflict in conflicts)
            {
                ResolveConflict(conflict.FileName, strategy);
            }
            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
 void OpenSavedGame(ConflictResolutionStrategy strategy)
 {
     SetStandBy("Opening using strategy: " + strategy);
     PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution(
         mSavedGameFilename,
         DataSource.ReadNetworkOnly,
         strategy,
         (status, openedFile) => {
         mStatus = "Open status for file " + mSavedGameFilename + ": " + status + "\n";
         if (openedFile != null)
         {
             mStatus += "Successfully opened file: " + openedFile.ToString();
             Logger.d("Opened file: " + openedFile.ToString());
             mCurrentSavedGame = openedFile;
         }
         EndStandBy();
     });
 }
Exemplo n.º 15
0
        public HttpResponseMessage ResolveConflict(string fileName, ConflictResolutionStrategy strategy)
        {
            Log.Debug("Resolving conflict of a file '{0}' by using {1} strategy", fileName, strategy);

            if (strategy == ConflictResolutionStrategy.CurrentVersion)
            {
                StrategyAsGetCurrent(fileName);
            }
            else if (strategy == ConflictResolutionStrategy.RemoteVersion)
            {
                StrategyAsGetRemote(fileName);
            }
            else
            {
                throw new NotSupportedException("NoOperation conflict resolution strategy, is not supported.");
            }

            return(GetEmptyMessage(HttpStatusCode.NoContent));
        }
        public SynchronizationThread(NoteRepository repository, IEnumerable <ISynchronizationFeedback> synclistener, AppSettings settings, IAlephDispatcher disp)
        {
            _repo     = repository;
            _listener = synclistener.ToList();

            _conflictStrategy = ConflictResolutionStrategyHelper.ToInterfaceType(settings.ConflictResolution);
            _noteDownloadEnableMultithreading    = repository.SupportsDownloadMultithreading;
            _noteDownloadParallelismLevel        = settings.NoteDownloadParallelismLevel;
            _noteDownloadParallelismThreshold    = settings.NoteDownloadParallelismThreshold;
            _noteNewDownloadEnableMultithreading = repository.SupportsNewDownloadMultithreading;
            _noteNewDownloadParallelismLevel     = settings.NoteNewDownloadParallelismLevel;
            _noteNewDownloadParallelismThreshold = settings.NoteNewDownloadParallelismThreshold;
            _noteUploadEnableMultithreading      = repository.SupportsUploadMultithreading;
            _noteUploadParallelismLevel          = settings.NoteUploadParallelismLevel;
            _noteUploadParallelismThreshold      = settings.NoteUploadParallelismThreshold;

            _dispatcher = disp;
            _comChannel = new ManualResetEvent(false);
        }
Exemplo n.º 17
0
		public bool TryResolveConflict(string fileName, ConflictItem conflict, RavenJObject localMetadata, RavenJObject remoteMetadata, out ConflictResolutionStrategy strategy)
		{
			foreach (var resolver in Resolvers)
			{
				if (resolver.TryResolve(fileName, localMetadata, remoteMetadata, out strategy) == false)
					continue;

				switch (strategy)
				{
					case ConflictResolutionStrategy.CurrentVersion:
						ApplyCurrentStrategy(fileName, conflict, localMetadata);
						return true;
					case ConflictResolutionStrategy.RemoteVersion:
						ApplyRemoteStrategy(fileName, conflict, localMetadata);
						return true;
				}
			}

			strategy = ConflictResolutionStrategy.NoResolution;
			return false;
		}
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!StringEx.IsNullOrWhiteSpace(nullColumnHack))
            {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(TAG));
                Log.E(TAG, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var t = Factory.StartNew(() =>
            {
                var lastInsertedId = -1L;
                var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

                try
                {
                    LastErrorCode = command.step();
                    command.Dispose();
                    if (LastErrorCode == SQLiteResult.ERROR)
                        throw new CouchbaseLiteException(raw.sqlite3_errmsg(_writeConnection), StatusCode.DbError);

                    int changes = _writeConnection.changes();
                    if (changes > 0)
                    {
                        lastInsertedId = _writeConnection.last_insert_rowid();
                    }

                    if (lastInsertedId == -1L)
                    {
                        if(conflictResolutionStrategy != ConflictResolutionStrategy.Ignore) {
                            Log.E(TAG, "Error inserting " + initialValues + " using " + command);
                            throw new CouchbaseLiteException("Error inserting " + initialValues + " using " + command, StatusCode.DbError);
                        }
                    } else
                    {
                        Log.V(TAG, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                    }

                } 
                catch (Exception ex)
                {
                    Log.E(TAG, "Error inserting into table " + table, ex);
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw;
                }
                return lastInsertedId;
            });

            var r = t.ConfigureAwait(false).GetAwaiter().GetResult();
            if (t.Exception != null)
                throw t.Exception;

            return r;
        }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        SqliteCommand GetInsertCommand (String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None) {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet = values.ValueSet();
            var sqlParams = new SqliteParameter[valueSet.LongCount()];
            var valueBuilder = new StringBuilder();
            var index = 0L;

            foreach(var column in valueSet)
            {
                if (index > 0) {
                         builder.Append(",");
                    valueBuilder.Append(",");
                }

                     builder.AppendFormat( "{0}", column.Key);
                valueBuilder.AppendFormat("@{0}", column.Key);

                sqlParams[index++] = new SqliteParameter(column.Key, column.Value);
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql = builder.ToString();
            var command = new SqliteCommand(sql, Connection, currentTransaction);
            command.Parameters.Clear();
            command.Parameters.AddRange(sqlParams);

            return command;
        }
Exemplo n.º 20
0
 public override RemoteUploadResult UploadNoteToRemote(ref INote note, out INote conflict, out bool keepNoteRemoteDirtyWithConflict, ConflictResolutionStrategy strategy)
 {
     conflict = null;
     keepNoteRemoteDirtyWithConflict = false;
     return(RemoteUploadResult.UpToDate);
 }
        public long InsertWithOnConflict (String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!String.IsNullOrWhiteSpace(nullColumnHack)) {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(Tag));
                Log.E(Tag, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

            var lastInsertedId = -1L;
            try {
                var result = command.Step();

                // Get the new row's id.
                // TODO.ZJG: This query should ultimately be replaced with a call to sqlite3_last_insert_rowid.
                var lastInsertedIndexCommand = Connection.Prepare("select last_insert_rowid()");
                var rowidResult =  lastInsertedIndexCommand.Step();
                if (rowidResult != SQLiteResult.ERROR)
                    throw new CouchbaseLiteException(lastInsertedIndexCommand.Connection.ErrorMessage(), StatusCode.DbError);
                lastInsertedId = Convert.ToInt64(lastInsertedIndexCommand[0]);
                lastInsertedIndexCommand.Dispose();
                if (lastInsertedId == -1L) {
                    Log.E(Tag, "Error inserting " + initialValues + " using " + command);
                } else {
                    Log.V(Tag, "Inserting row " + lastInsertedId + " from " + initialValues + " using " + command);
                }
            } catch (Exception ex) {
                Log.E(Tag, "Error inserting into table " + table, ex);
            } finally {
                command.Dispose();
            }
            return lastInsertedId;
        }
Exemplo n.º 22
0
        private void InternalOpen(string filename, DataSource source, ConflictResolutionStrategy resolutionStrategy,
                                  bool prefetchDataOnConflict, ConflictCallback conflictCallback,
                                  Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback)
        {
            int conflictPolicy; // SnapshotsClient.java#RetentionPolicy

            switch (resolutionStrategy)
            {
            case ConflictResolutionStrategy.UseLastKnownGood:
                conflictPolicy = 2 /* RESOLUTION_POLICY_LAST_KNOWN_GOOD */;
                break;

            case ConflictResolutionStrategy.UseMostRecentlySaved:
                conflictPolicy = 3 /* RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED */;
                break;

            case ConflictResolutionStrategy.UseLongestPlaytime:
                conflictPolicy = 1 /* RESOLUTION_POLICY_LONGEST_PLAYTIME*/;
                break;

            case ConflictResolutionStrategy.UseManual:
                conflictPolicy = -1 /* RESOLUTION_POLICY_MANUAL */;
                break;

            default:
                conflictPolicy = 3 /* RESOLUTION_POLICY_MOST_RECENTLY_MODIFIED */;
                break;
            }

            using (var task =
                       mSnapshotsClient.Call <AndroidJavaObject>("open", filename, /* createIfNotFound= */ true,
                                                                 conflictPolicy))
            {
                AndroidTaskUtils.AddOnSuccessListener <AndroidJavaObject>(
                    task,
                    dataOrConflict =>
                {
                    if (dataOrConflict.Call <bool>("isConflict"))
                    {
                        var conflict = dataOrConflict.Call <AndroidJavaObject>("getConflict");
                        AndroidSnapshotMetadata original =
                            new AndroidSnapshotMetadata(conflict.Call <AndroidJavaObject>("getSnapshot"));
                        AndroidSnapshotMetadata unmerged =
                            new AndroidSnapshotMetadata(
                                conflict.Call <AndroidJavaObject>("getConflictingSnapshot"));

                        // Instantiate the conflict resolver. Note that the retry callback closes over
                        // all the parameters we need to retry the open attempt. Once the conflict is
                        // resolved by invoking the appropriate resolution method on
                        // AndroidConflictResolver, the resolver will invoke this callback, which will
                        // result in this method being re-executed. This recursion will continue until
                        // all conflicts are resolved or an error occurs.
                        AndroidConflictResolver resolver = new AndroidConflictResolver(
                            this,
                            mSnapshotsClient,
                            conflict,
                            original,
                            unmerged,
                            completedCallback,
                            () => InternalOpen(filename, source, resolutionStrategy,
                                               prefetchDataOnConflict,
                                               conflictCallback, completedCallback));

                        var originalBytes = original.JavaContents.Call <byte[]>("readFully");
                        var unmergedBytes = unmerged.JavaContents.Call <byte[]>("readFully");
                        conflictCallback(resolver, original, originalBytes, unmerged, unmergedBytes);
                    }
                    else
                    {
                        using (var snapshot = dataOrConflict.Call <AndroidJavaObject>("getData"))
                        {
                            AndroidJavaObject metadata = snapshot.Call <AndroidJavaObject>("freeze");
                            completedCallback(SavedGameRequestStatus.Success,
                                              new AndroidSnapshotMetadata(metadata));
                        }
                    }
                });

                AddOnFailureListenerWithSignOut(
                    task,
                    exception => {
                    OurUtils.Logger.d("InternalOpen has failed: " + exception.Call <string>("toString"));
                    var status = mAndroidClient.IsAuthenticated() ?
                                 SavedGameRequestStatus.InternalError :
                                 SavedGameRequestStatus.AuthenticationError;
                    completedCallback(status, null);
                }
                    );
            }
        }
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!String.IsNullOrWhiteSpace(nullColumnHack))
            {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(Tag));
                Log.E(Tag, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

            var lastInsertedId = -1L;

            try {
                var result = command.Step();

                // Get the new row's id.
                // TODO.ZJG: This query should ultimately be replaced with a call to sqlite3_last_insert_rowid.
                var lastInsertedIndexCommand = Connection.Prepare("select last_insert_rowid()");
                var rowidResult = lastInsertedIndexCommand.Step();
                if (rowidResult != SQLiteResult.ERROR)
                {
                    throw new CouchbaseLiteException(lastInsertedIndexCommand.Connection.ErrorMessage(), StatusCode.DbError);
                }
                lastInsertedId = Convert.ToInt64(lastInsertedIndexCommand[0]);
                lastInsertedIndexCommand.Dispose();
                if (lastInsertedId == -1L)
                {
                    Log.E(Tag, "Error inserting " + initialValues + " using " + command);
                }
                else
                {
                    Log.V(Tag, "Inserting row " + lastInsertedId + " from " + initialValues + " using " + command);
                }
            } catch (Exception ex) {
                Log.E(Tag, "Error inserting into table " + table, ex);
            } finally {
                command.Dispose();
            }
            return(lastInsertedId);
        }
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (_readOnly) {
                throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.Forbidden, TAG,
                    "Attempting to write to a readonly database");
            }

            if (!StringEx.IsNullOrWhiteSpace(nullColumnHack)) {
                throw new InvalidOperationException("Don't use nullColumnHack");
            }

            Log.To.TaskScheduling.V(TAG, "Scheduling InsertWithOnConflict");
            var t = Factory.StartNew(() =>
            {
                Log.To.TaskScheduling.V(TAG, "Running InsertWithOnConflict");
                var lastInsertedId = -1L;
                var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

                try {
                    LastErrorCode = command.step();
                    command.Dispose();
                    if (LastErrorCode == raw.SQLITE_ERROR) {
                        throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                            raw.sqlite3_errmsg(_writeConnection));
                    }

                    int changes = _writeConnection.changes();
                    if (changes > 0)
                    {
                        lastInsertedId = _writeConnection.last_insert_rowid();
                    }

                    if (lastInsertedId == -1L) {
                        if(conflictResolutionStrategy != ConflictResolutionStrategy.Ignore) {
                            throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                                "Error inserting {0} using {1}", initialValues, command);
                        }
                    } else {
                        Log.To.Database.V(TAG, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                    }

                } 
                catch(CouchbaseLiteException) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    Log.To.Database.E(TAG, "Error inserting into table {0}, rethrowing...", table);
                    throw;
                } catch (Exception ex) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw Misc.CreateExceptionAndLog(Log.To.Database, ex, StatusCode.DbError, TAG, 
                        "Error inserting into table {0}", table);
                }

                return lastInsertedId;
            });

            var r = t.ConfigureAwait(false).GetAwaiter().GetResult();
            if (t.Exception != null)
                throw t.Exception;

            return r;
        }
Exemplo n.º 25
0
        public bool TryResolveConflict(string fileName, ConflictItem conflict, RavenJObject localMetadata, RavenJObject remoteMetadata, out ConflictResolutionStrategy strategy)
        {
            foreach (var resolver in Resolvers)
            {
                if (resolver.TryResolve(fileName, localMetadata, remoteMetadata, out strategy) == false)
                {
                    continue;
                }

                switch (strategy)
                {
                case ConflictResolutionStrategy.CurrentVersion:
                    ApplyCurrentStrategy(fileName, conflict, localMetadata);
                    return(true);

                case ConflictResolutionStrategy.RemoteVersion:
                    ApplyRemoteStrategy(fileName, conflict, localMetadata);
                    return(true);
                }
            }

            strategy = ConflictResolutionStrategy.NoResolution;
            return(false);
        }
        public override long InsertWithOnConflict (String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!String.IsNullOrWhiteSpace(nullColumnHack)) {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(Tag));
                Log.E(Tag, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

            var lastInsertedId = -1L;
            try {
                command.ExecuteNonQuery();

                // Get the new row's id.
                // TODO.ZJG: This query should ultimately be replaced with a call to sqlite3_last_insert_rowid.
                var lastInsertedIndexCommand = new SqliteCommand("select last_insert_rowid()", Connection, currentTransaction);
                lastInsertedId = (Int64)lastInsertedIndexCommand.ExecuteScalar();
                lastInsertedIndexCommand.Dispose();
                if (lastInsertedId == -1L) {
                    Log.E(Tag, "Error inserting " + initialValues + " using " + command.CommandText);
                } else {
                    Log.V(Tag, "Inserting row " + lastInsertedId + " from " + initialValues + " using " + command.CommandText);
                }
            } catch (Exception ex) {
                Log.E(Tag, "Error inserting into table " + table, ex);
            } finally {
                command.Dispose();
            }
            return lastInsertedId;
        }
Exemplo n.º 27
0
    internal void OpenSavedGame(ConflictResolutionStrategy strategy)
    {
        SetStandBy("Opening using strategy: " + strategy);
        PlayGamesPlatform.Instance.SavedGame.OpenWithAutomaticConflictResolution(
            mSavedGameFilename,
            DataSource.ReadNetworkOnly,
            strategy,
            (status, openedFile) =>
            {
                mStatus = "Open status for file " + mSavedGameFilename + ": " + status + "\n";
                if (openedFile != null)
                {
                    mStatus += "Successfully opened file: " + openedFile.ToString();
                    Logger.d("Opened file: " + openedFile.ToString());
                    mCurrentSavedGame = openedFile;
                }

                EndStandBy();
            });
    }
Exemplo n.º 28
0
        public async Task ResolveConflictAsync(string filename, ConflictResolutionStrategy strategy)
        {
            var requestUriString = string.Format("{0}/synchronization/resolveConflict/{1}?strategy={2}",
                baseUrl, Uri.EscapeDataString(filename),
                Uri.EscapeDataString(strategy.ToString()));

            using (var request = RequestFactory.CreateHttpJsonRequest(new CreateHttpJsonRequestParams(this, requestUriString, "PATCH", Credentials, Conventions)).AddOperationHeaders(OperationsHeaders))
            {
                try
                {
                    await request.ExecuteRequestAsync().ConfigureAwait(false);
                }
                catch (Exception e)
                {
                    throw e.SimplifyException();
                }
            }
        }
Exemplo n.º 29
0
        public override RemoteUploadResult UploadNoteToRemote(ref INote inote, out INote conflict, ConflictResolutionStrategy strategy)
        {
            FilesystemNote note = (FilesystemNote)inote;

            var path = note.GetPath(_config);

            if (File.Exists(note.PathRemote) && path != note.PathRemote && !File.Exists(path))
            {
                _logger.Debug(FilesystemPlugin.Name, "Upload note to changed remote path");                 // path changed and new path does not exist

                WriteNoteToPath(note, path);
                conflict = null;
                ANFileSystemUtil.DeleteFileAndFolderIfEmpty(FilesystemPlugin.Name, _logger, _config.Folder, note.PathRemote);
                note.PathRemote = path;
                return(RemoteUploadResult.Uploaded);
            }
            else if (File.Exists(note.PathRemote) && path != note.PathRemote && File.Exists(path))
            {
                _logger.Debug(FilesystemPlugin.Name, "Upload note to changed remote path");                 // path changed and new path does exist

                var conf = ReadNoteFromPath(note.PathRemote);
                if (conf.ModificationDate > note.ModificationDate)
                {
                    conflict = conf;
                    if (strategy == ConflictResolutionStrategy.UseClientCreateConflictFile || strategy == ConflictResolutionStrategy.UseClientVersion || strategy == ConflictResolutionStrategy.ManualMerge)
                    {
                        WriteNoteToPath(note, path);
                        ANFileSystemUtil.DeleteFileAndFolderIfEmpty(FilesystemPlugin.Name, _logger, _config.Folder, note.PathRemote);
                        note.PathRemote = path;
                        return(RemoteUploadResult.Conflict);
                    }
                    else
                    {
                        note.PathRemote = path;
                        return(RemoteUploadResult.Conflict);
                    }
                }
                else
                {
                    WriteNoteToPath(note, path);
                    conflict = null;
                    ANFileSystemUtil.DeleteFileAndFolderIfEmpty(FilesystemPlugin.Name, _logger, _config.Folder, note.PathRemote);
                    note.PathRemote = path;
                    return(RemoteUploadResult.Uploaded);
                }
            }
            else if (File.Exists(path))             // normal update
            {
                var conf = ReadNoteFromPath(path);
                if (conf.ModificationDate > note.ModificationDate)
                {
                    conflict = conf;
                    if (strategy == ConflictResolutionStrategy.UseClientCreateConflictFile || strategy == ConflictResolutionStrategy.UseClientVersion)
                    {
                        WriteNoteToPath(note, path);
                        if (note.PathRemote != "")
                        {
                            ANFileSystemUtil.DeleteFileAndFolderIfEmpty(FilesystemPlugin.Name, _logger, _config.Folder, note.PathRemote);
                        }
                        note.PathRemote = path;
                        return(RemoteUploadResult.Conflict);
                    }
                    else
                    {
                        note.PathRemote = path;
                        return(RemoteUploadResult.Conflict);
                    }
                }
                else
                {
                    WriteNoteToPath(note, path);
                    conflict        = null;
                    note.PathRemote = path;
                    return(RemoteUploadResult.Uploaded);
                }
            }
            else             // new file
            {
                WriteNoteToPath(note, path);
                conflict        = null;
                note.PathRemote = path;
                return(RemoteUploadResult.Uploaded);
            }
        }
		public override long InsertWithOnConflict (string table, string nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
		{
			throw new NotImplementedException ();
		}
Exemplo n.º 31
0
		public override bool TryResolve(string fileName, RavenJObject localMedatada, RavenJObject remoteMetadata, out ConflictResolutionStrategy resolutionStrategy)
		{
			resolutionStrategy = ConflictResolutionStrategy.RemoteVersion;
			return true;
		}
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!IsOpen) {
                throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadRequest, TAG,
                    "GetInsertCommand called on closed database");
            }

            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index = 0;

            var args = new object[valueSet.Count];

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.Append("?");

                args[index] = column.Value;

                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql = builder.ToString();
            sqlite3_stmt command = null;
            if (args != null) {
                Log.To.Database.V(TAG, "Preparing statement: '{0}' with values: {1}", sql, new SecureLogJsonString(args, LogMessageSensitivity.PotentiallyInsecure));
            } else {
                Log.To.Database.V(TAG, "Preparing statement: '{0}'", sql);
            }

            command = BuildCommand(_writeConnection, sql, args);

            return command;
        }
Exemplo n.º 33
0
        public override RemoteUploadResult UploadNoteToRemote(ref INote inote, out INote conflict, ConflictResolutionStrategy strategy)
        {
            var note = (EvernoteNote)inote;

            var remote = bucket.Notes.FirstOrDefault(p => Guid.Parse(p.Guid) == note.ID);

            remoteDirty = true;

            if (remote == null)
            {
                inote = APICreateNewNote(note);

                conflict = null;
                return(RemoteUploadResult.Uploaded);
            }
            else
            {
                if (remote.UpdateSequenceNum > note.UpdateSequenceNumber)
                {
                    if (strategy == ConflictResolutionStrategy.UseClientVersion || strategy == ConflictResolutionStrategy.UseClientCreateConflictFile || strategy == ConflictResolutionStrategy.ManualMerge)
                    {
                        conflict = APIDownloadNote(note.ID);
                        inote    = APIUpdateNote(note);
                        return(RemoteUploadResult.Conflict);
                    }
                    else if (strategy == ConflictResolutionStrategy.UseServerVersion || strategy == ConflictResolutionStrategy.UseServerCreateConflictFile)
                    {
                        conflict = inote.Clone();
                        inote    = APIDownloadNote(note.ID);
                        return(RemoteUploadResult.Conflict);
                    }
                    else
                    {
                        throw new ArgumentException("strategy == " + strategy);
                    }
                }
                else
                {
                    inote = APIUpdateNote(note);

                    conflict = null;
                    return(RemoteUploadResult.Uploaded);
                }
            }
        }
 public void OpenWithAutomaticConflictResolution(string filename, DataSource source,
                                                 ConflictResolutionStrategy resolutionStrategy,
                                                 Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback)
 {
     OpenWithAutomaticConflictResolution(filename, source, resolutionStrategy, false, null, completedCallback);
 }
Exemplo n.º 35
0
 public void OpenWithAutomaticConflictResolution(string filename, DataSource source,
                                             ConflictResolutionStrategy resolutionStrategy,
                                             Action<SavedGameRequestStatus, ISavedGameMetadata> callback)
 {
     throw new NotImplementedException(mMessage);
 }
        private void InternalOpen(string filename, DataSource source, ConflictResolutionStrategy resolutionStrategy,
                                  bool prefetchDataOnConflict, ConflictCallback conflictCallback,
                                  Action <SavedGameRequestStatus, ISavedGameMetadata> completedCallback)
        {
            Types.SnapshotConflictPolicy policy;
            switch (resolutionStrategy)
            {
            case ConflictResolutionStrategy.UseLastKnownGood:
                policy = Types.SnapshotConflictPolicy.LAST_KNOWN_GOOD;
                break;

            case ConflictResolutionStrategy.UseMostRecentlySaved:
                policy = Types.SnapshotConflictPolicy.MOST_RECENTLY_MODIFIED;
                break;

            case ConflictResolutionStrategy.UseLongestPlaytime:
                policy = Types.SnapshotConflictPolicy.LONGEST_PLAYTIME;
                break;

            case ConflictResolutionStrategy.UseManual:
                policy = Types.SnapshotConflictPolicy.MANUAL;
                break;

            default:
                policy = Types.SnapshotConflictPolicy.MOST_RECENTLY_MODIFIED;
                break;
            }

            mSnapshotManager.Open(filename, AsDataSource(source), policy,
                                  response =>
            {
                if (!response.RequestSucceeded())
                {
                    completedCallback(AsRequestStatus(response.ResponseStatus()), null);
                }
                else if (response.ResponseStatus() == Status.SnapshotOpenStatus.VALID)
                {
                    completedCallback(SavedGameRequestStatus.Success, response.Data());
                }
                else if (response.ResponseStatus() ==
                         Status.SnapshotOpenStatus.VALID_WITH_CONFLICT)
                {
                    // If we get here, manual conflict resolution is required.
                    NativeSnapshotMetadata original = response.ConflictOriginal();
                    NativeSnapshotMetadata unmerged = response.ConflictUnmerged();

                    // Instantiate the conflict resolver. Note that the retry callback closes over
                    // all the parameters we need to retry the open attempt. Once the conflict is
                    // resolved by invoking the appropriate resolution method on
                    // NativeConflictResolver, the resolver will invoke this callback, which will
                    // result in this method being re-executed. This recursion will continue until
                    // all conflicts are resolved or an error occurs.
                    NativeConflictResolver resolver = new NativeConflictResolver(
                        mSnapshotManager,
                        response.ConflictId(),
                        original,
                        unmerged,
                        completedCallback,
                        () => InternalOpen(filename, source, resolutionStrategy,
                                           prefetchDataOnConflict,
                                           conflictCallback, completedCallback)
                        );

                    // If we don't have to pre-fetch the saved games' binary data, we can
                    // immediately invoke the conflict callback. Note that this callback is
                    // constructed to execute on the game thread in
                    // OpenWithManualConflictResolution.
                    if (!prefetchDataOnConflict)
                    {
                        conflictCallback(resolver, original, null, unmerged, null);
                        return;
                    }

                    // If we have to prefetch the data, we delegate invoking the conflict resolution
                    // callback to the joiner instance (once both callbacks resolve, the joiner will
                    // invoke the lambda that we declare here, using the fetched data).
                    Prefetcher joiner = new Prefetcher((originalData, unmergedData) =>
                                                       conflictCallback(resolver, original, originalData, unmerged, unmergedData),
                                                       completedCallback);

                    // Kick off the read calls.
                    mSnapshotManager.Read(original, joiner.OnOriginalDataRead);
                    mSnapshotManager.Read(unmerged, joiner.OnUnmergedDataRead);
                }
                else
                {
                    Logger.e("Unhandled response status");
                    completedCallback(SavedGameRequestStatus.InternalError, null);
                }
            });
        }
Exemplo n.º 37
0
 public abstract long InsertWithOnConflict(string table, string nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy);
        public long InsertWithOnConflict (String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!String.IsNullOrWhiteSpace(nullColumnHack)) {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(Tag));
                Log.E(Tag, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var lastInsertedId = -1L;
            var command = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

            try {
                int result;
                lock (dbLock) {
                    result = command.step ();
                }
                if (result == SQLiteResult.ERROR)
                    throw new CouchbaseLiteException(raw.sqlite3_errmsg(db), StatusCode.DbError);

                int changes;
                lock (dbLock) {
                    changes = db.changes ();
                }
                if (changes > 0) 
                {
                    lock (dbLock) {
                        lastInsertedId = db.last_insert_rowid();
                    }
                }

                if (lastInsertedId == -1L) {
                    Log.E(Tag, "Error inserting " + initialValues + " using " + command);
                    throw new CouchbaseLiteException("Error inserting " + initialValues + " using " + command, StatusCode.DbError);
                } else {
                    Log.V(Tag, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                }

            } catch (Exception ex) {
                Log.E(Tag, "Error inserting into table " + table, ex);
                throw;
            } finally {
                lock (dbLock) {
                    command.Dispose();
                }
            }

            return lastInsertedId;
        }
Exemplo n.º 39
0
        public override RemoteUploadResult UploadNoteToRemote(ref INote inote, out INote conflict, ConflictResolutionStrategy strategy)
        {
            using (var web = CreateAuthenticatedClient())
            {
                var note = (SimpleNote)inote;

                var remote = buckets.index.FirstOrDefault(p => p.id == note.ID);

                if (remote == null)
                {
                    conflict = null;
                    inote    = SimpleNoteAPI.UploadNewNote(web, note, _config, this);
                    return(RemoteUploadResult.Uploaded);
                }
                else
                {
                    if (remote.v > note.LocalVersion)
                    {
                        if (strategy == ConflictResolutionStrategy.UseClientVersion || strategy == ConflictResolutionStrategy.UseClientCreateConflictFile || strategy == ConflictResolutionStrategy.ManualMerge)
                        {
                            conflict = SimpleNoteAPI.GetNoteData(web, note.ID, _config, this);
                            inote    = SimpleNoteAPI.ChangeExistingNote(web, note, _config, this, out _);
                            return(RemoteUploadResult.Conflict);
                        }
                        else if (strategy == ConflictResolutionStrategy.UseServerVersion || strategy == ConflictResolutionStrategy.UseServerCreateConflictFile)
                        {
                            conflict = inote.Clone();
                            inote    = SimpleNoteAPI.GetNoteData(web, note.ID, _config, this);
                            return(RemoteUploadResult.Conflict);
                        }
                        else
                        {
                            throw new ArgumentException("strategy == " + strategy);
                        }
                    }
                    else
                    {
                        conflict = null;
                        bool updated;
                        inote = SimpleNoteAPI.ChangeExistingNote(web, note, _config, this, out updated);
                        return(updated ? RemoteUploadResult.Uploaded : RemoteUploadResult.UpToDate);
                    }
                }
            }
        }
		public HttpResponseMessage ResolveConflict(string fileName, ConflictResolutionStrategy strategy)
		{
			Log.Debug("Resolving conflict of a file '{0}' by using {1} strategy", fileName, strategy);

			if (strategy == ConflictResolutionStrategy.CurrentVersion)
			{
				StrategyAsGetCurrent(fileName);
			}
			else
			{
				StrategyAsGetRemote(fileName);
			}

			return new HttpResponseMessage(HttpStatusCode.OK);
		}
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand (String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None) {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index = 0;

            foreach(var column in valueSet)
            {
                if (index > 0) {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat( "{0}", column.Key);
                valueBuilder.Append("@");
                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql = builder.ToString();
            var command = Connection.Prepare(sql);

            index = 1;
            foreach(var val in valueSet)
            {
                var key = val.Key;
                command.Bind(index++, values[key]);
            }

            return command;
        }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand (String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!IsOpen)
            {
                Open(Path);
            }
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None) {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index = 0;

            var args = new object[valueSet.Count];

            foreach(var column in valueSet)
            {
                if (index > 0) {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat( "{0}", column.Key);
                valueBuilder.Append("?");

                args[index] = column.Value;

                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql = builder.ToString();
            sqlite3_stmt command;
            lock (dbLock) {
                command = db.prepare (sql);
                command.bind (args);
            }

            return command;
        }
Exemplo n.º 43
0
 public override bool TryResolve(string fileName, RavenJObject localMedatada, RavenJObject remoteMetadata, out ConflictResolutionStrategy resolutionStrategy)
 {
     resolutionStrategy = ConflictResolutionStrategy.CurrentVersion;
     return(true);
 }
		public abstract bool TryResolve(string fileName, RavenJObject localMedatada, RavenJObject remoteMetadata, out ConflictResolutionStrategy resolutionStrategy); 
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!IsOpen)
            {
                throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.BadRequest, TAG,
                                                 "GetInsertCommand called on closed database");
            }

            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet     = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index        = 0;

            var args = new object[valueSet.Count];

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.Append("?");

                args[index] = column.Value;

                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var          sql     = builder.ToString();
            sqlite3_stmt command = null;

            if (args != null)
            {
                Log.To.Database.V(TAG, "Preparing statement: '{0}' with values: {1}", sql, new SecureLogJsonString(args, LogMessageSensitivity.PotentiallyInsecure));
            }
            else
            {
                Log.To.Database.V(TAG, "Preparing statement: '{0}'", sql);
            }

            command = BuildCommand(_writeConnection, sql, args);

            return(command);
        }
Exemplo n.º 46
0
 public void OpenWithAutomaticConflictResolution(string filename, DataSource source,
                                                 ConflictResolutionStrategy resolutionStrategy,
                                                 Action <SavedGameRequestStatus, ISavedGameMetadata> callback)
 {
     throw new NotImplementedException(mMessage);
 }
        /// <summary>
        /// Avoids the additional database trip that using SqliteCommandBuilder requires.
        /// </summary>
        /// <returns>The insert command.</returns>
        /// <param name="table">Table.</param>
        /// <param name="values">Values.</param>
        /// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
        sqlite3_stmt GetInsertCommand(String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!IsOpen)
            {
                Open(Path);
            }
            var builder = new StringBuilder("INSERT");

            if (conflictResolutionStrategy != ConflictResolutionStrategy.None)
            {
                builder.Append(" OR ");
                builder.Append(conflictResolutionStrategy);
            }

            builder.Append(" INTO ");
            builder.Append(table);
            builder.Append(" (");

            // Append our content column names and create our SQL parameters.
            var valueSet = values.ValueSet();
            var valueBuilder = new StringBuilder();
            var index = 0;

            var args = new object[valueSet.Count];

            foreach (var column in valueSet)
            {
                if (index > 0)
                {
                    builder.Append(",");
                    valueBuilder.Append(",");
                }

                builder.AppendFormat("{0}", column.Key);
                valueBuilder.Append("?");

                args[index] = column.Value;

                index++;
            }

            builder.Append(") VALUES (");
            builder.Append(valueBuilder);
            builder.Append(")");

            var sql = builder.ToString();
            sqlite3_stmt command = null;
            if (args != null)
            {
                Log.D(TAG, "Preparing statement: '{0}' with values: {1}", sql, String.Join(", ", args.Select(o => o == null ? "null" : o.ToString()).ToArray()));
            }
            else
            {
                Log.D(TAG, "Preparing statement: '{0}'", sql);
            }

            command = BuildCommand(_writeConnection, sql, args);

            return command;
        }
		/// <summary>
		/// Avoids the additional database trip that using SqliteCommandBuilder requires.
		/// </summary>
		/// <returns>The insert command.</returns>
		/// <param name="table">Table.</param>
		/// <param name="values">Values.</param>
		/// <param name="conflictResolutionStrategy">Conflict resolution strategy.</param>
		ISQLiteStatement GetInsertCommand (String table, ContentValues values, ConflictResolutionStrategy conflictResolutionStrategy)
		{
			var builder = new StringBuilder("INSERT");

			if (conflictResolutionStrategy != ConflictResolutionStrategy.None) {
				builder.Append(" OR ");
				builder.Append(conflictResolutionStrategy);
			}

			builder.Append(" INTO ");
			builder.Append(table);
			builder.Append(" (");

			// Append our content column names and create our SQL parameters.
			var valueSet = values.ValueSet();
			var sqlParams = new Dictionary<string, object> (); 
			var valueBuilder = new StringBuilder();
			var index = 0L;

			foreach(var column in valueSet)
			{
				if (index > 0) {
					builder.Append(",");
					valueBuilder.Append(",");
				}

				builder.AppendFormat( "{0}", column.Key);
				valueBuilder.AppendFormat("@{0}", column.Key);

				index++;
				sqlParams.Add (column.Key, column.Value);
			}

			builder.Append(") VALUES (");
			builder.Append(valueBuilder);
			builder.Append(")");

			var stmt = connection.Prepare (builder.ToString ());
			foreach (var p in sqlParams)
				stmt.Bind (p.Key, p.Value);

			return stmt;
		}
Exemplo n.º 49
0
        public HttpResponseMessage ResolveConflict(string filename, ConflictResolutionStrategy strategy)
		{
            var canonicalFilename = FileHeader.Canonize(filename);

            Log.Debug("Resolving conflict of a file '{0}' by using {1} strategy", filename, strategy);

			switch (strategy)
			{
				case ConflictResolutionStrategy.CurrentVersion:

					Storage.Batch(accessor =>
					{
                        var localMetadata = accessor.GetFile(canonicalFilename, 0, 0).Metadata;
                        var conflict = accessor.GetConfigurationValue<ConflictItem>(RavenFileNameHelper.ConflictConfigNameForFile(canonicalFilename));

                        ConflictResolver.ApplyCurrentStrategy(canonicalFilename, conflict, localMetadata);

                        accessor.UpdateFileMetadata(canonicalFilename, localMetadata, null);

                        ConflictArtifactManager.Delete(canonicalFilename, accessor);
					});

					Publisher.Publish(new ConflictNotification
					{
                        FileName = filename,
						Status = ConflictStatus.Resolved
					});

					break;
				case ConflictResolutionStrategy.RemoteVersion:

					Storage.Batch(accessor =>
					{
                        var localMetadata = accessor.GetFile(canonicalFilename, 0, 0).Metadata;
                        var conflict = accessor.GetConfig(RavenFileNameHelper.ConflictConfigNameForFile(canonicalFilename)).JsonDeserialization<ConflictItem>();

                        ConflictResolver.ApplyRemoteStrategy(canonicalFilename, conflict, localMetadata);

                        accessor.UpdateFileMetadata(canonicalFilename, localMetadata, null);

                        // ConflictArtifactManager.Delete(canonicalFilename, accessor); - intentionally not deleting, conflict item will be removed when a remote file is put
					});

					SynchronizationTask.Context.NotifyAboutWork();

					break;
				default:
					throw new NotSupportedException(string.Format("{0} is not the valid strategy to resolve a conflict", strategy));
			}

            return GetEmptyMessage(HttpStatusCode.NoContent);
		}
Exemplo n.º 50
0
        public override RemoteUploadResult UploadNoteToRemote(ref INote inote, out INote conflict, ConflictResolutionStrategy strategy)
        {
            var note = (StandardFileNote)inote;

            if (_syncResult.saved_notes.Any(n => n.ID == note.ID))
            {
                note.ApplyUpdatedData(_syncResult.saved_notes.First(n => n.ID == note.ID));
                conflict = null;
                return(RemoteUploadResult.Uploaded);
            }

            if (_syncResult.retrieved_notes.Any(n => n.ID == note.ID))
            {
                _logger.Warn(StandardNotePlugin.Name, "Uploaded note found in retrieved notes ... upload failed ?");
                note.ApplyUpdatedData(_syncResult.retrieved_notes.First(n => n.ID == note.ID));
                conflict = null;
                return(RemoteUploadResult.Merged);
            }

            if (_syncResult.error_notes.Any(n => n.ID == note.ID))
            {
                throw new Exception("Could not upload note - server returned note in {unsaved_notes}");
            }

            if (_syncResult.conflict_notes.Any(n => n.ID == note.ID))
            {
                conflict = _syncResult.conflict_notes.First(n => n.ID == note.ID);
                return(RemoteUploadResult.Conflict);
            }

            conflict = null;
            return(RemoteUploadResult.UpToDate);
        }
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (!String.IsNullOrWhiteSpace(nullColumnHack))
            {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(Tag));
                Log.E(Tag, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var lastInsertedId = -1L;
            var command        = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

            try {
                int result;
                lock (dbLock) {
                    result = command.step();
                }
                if (result == SQLiteResult.ERROR)
                {
                    throw new CouchbaseLiteException(raw.sqlite3_errmsg(db), StatusCode.DbError);
                }

                int changes;
                lock (dbLock) {
                    changes = db.changes();
                }
                if (changes > 0)
                {
                    lock (dbLock) {
                        lastInsertedId = db.last_insert_rowid();
                    }
                }

                if (lastInsertedId == -1L)
                {
                    Log.E(Tag, "Error inserting " + initialValues + " using " + command);
                    throw new CouchbaseLiteException("Error inserting " + initialValues + " using " + command, StatusCode.DbError);
                }
                else
                {
                    Log.V(Tag, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                }
            } catch (Exception ex) {
                Log.E(Tag, "Error inserting into table " + table, ex);
                throw;
            } finally {
                lock (dbLock) {
                    command.Dispose();
                }
            }

            return(lastInsertedId);
        }
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (_readOnly)
            {
                throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.Forbidden, TAG,
                                                 "Attempting to write to a readonly database");
            }

            if (!StringEx.IsNullOrWhiteSpace(nullColumnHack))
            {
                throw new InvalidOperationException("Don't use nullColumnHack");
            }

            Log.To.TaskScheduling.V(TAG, "Scheduling InsertWithOnConflict");
            var t = Factory.StartNew(() =>
            {
                Log.To.TaskScheduling.V(TAG, "Running InsertWithOnConflict");
                var lastInsertedId = -1L;
                var command        = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

                try {
                    LastErrorCode = command.step();
                    command.Dispose();
                    if (LastErrorCode == raw.SQLITE_ERROR)
                    {
                        throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                                                         raw.sqlite3_errmsg(_writeConnection));
                    }

                    int changes = _writeConnection.changes();
                    if (changes > 0)
                    {
                        lastInsertedId = _writeConnection.last_insert_rowid();
                    }

                    if (lastInsertedId == -1L)
                    {
                        if (conflictResolutionStrategy != ConflictResolutionStrategy.Ignore)
                        {
                            throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                                                             "Error inserting {0} using {1}", initialValues, command);
                        }
                    }
                    else
                    {
                        Log.To.Database.V(TAG, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                    }
                }
                catch (CouchbaseLiteException) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    Log.To.Database.E(TAG, "Error inserting into table {0}, rethrowing...", table);
                    throw;
                } catch (Exception ex) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw Misc.CreateExceptionAndLog(Log.To.Database, ex, StatusCode.DbError, TAG,
                                                     "Error inserting into table {0}", table);
                }

                return(lastInsertedId);
            });

            var r = t.ConfigureAwait(false).GetAwaiter().GetResult();

            if (t.Exception != null)
            {
                throw t.Exception;
            }

            return(r);
        }