예제 #1
0
파일: Brenn.svc.cs 프로젝트: abrkn/Brenn
        public SyncResponse Sync(SyncRequest request)
        {
            lock (this.changeSetLock)
            {
                if (this.sharedChangeSetN == 0)
                {
                    using (var db = new BrennContext())
                    {
                        this.sharedChangeSetN =
                            new[]
                                {
                                    db.Expenses.Max<Expense, int?>(e => e.ChangeSetN),
                                    db.Trips.Max<Trip, int?>(e => e.ChangeSetN),
                                    db.People.Max<Person, int?>(e => e.ChangeSetN)
                                }.Max().GetValueOrDefault(1);
                    }
                }
            }

            var anyUpdates = (request.ExpenseUpdates == null ? 0 : request.ExpenseUpdates.Count) +
                             (request.TripUpdates == null ? 0 : request.TripUpdates.Count) +
                             (request.PersonUpdates == null ? 0 : request.PersonUpdates.Count) > 0;

            var changeSetN = anyUpdates ? Interlocked.Increment(ref this.sharedChangeSetN) : this.sharedChangeSetN;

            var response = new SyncResponse
                {
                    ExpenseUpdateResults = new List<UpdateResult>(),
                    TripUpdateResults = new List<UpdateResult>(),
                    PersonUpdateResults = new List<UpdateResult>(),
                    ServerChangeSetN = changeSetN
                };

            var updatedExpenseIds = new List<int>();
            var updatedTripIds = new List<int>();
            var updatedPersonIds = new List<int>();

            PerformExpenseUpdates(request, response, updatedExpenseIds);
            PerformTripUpdates(request, response, updatedTripIds);
            PerformPersonUpdates(request, response, updatedPersonIds);

            using (var db = new BrennContext())
            {
                ((IObjectContextAdapter)db).ObjectContext.ContextOptions.ProxyCreationEnabled = false;

                response.Expenses =
                    new List<Expense>(
                        db.Expenses.Include("Receivers").Where(
                            e => e.ChangeSetN > request.ClientChangeSetN && !updatedExpenseIds.Contains(e.ExpenseId)));

                response.Trips =
                    new List<Trip>(
                        db.Trips
                        .Where(
                            e => e.ChangeSetN > request.ClientChangeSetN && !updatedTripIds.Contains(e.TripId)));

                response.Trips.ForEach(t => t.Expenses = null);

                response.People =
                    new List<Person>(
                        db.People
                        .Where(e => e.ChangeSetN > request.ClientChangeSetN && !updatedPersonIds.Contains(e.PersonId)));
            }

            return response;
        }
예제 #2
0
파일: Brenn.svc.cs 프로젝트: abrkn/Brenn
        private static void PerformPersonUpdates(
            SyncRequest request, SyncResponse response, ICollection<int> updatedPersonIds)
        {
            if (request.PersonUpdates == null)
            {
                return;
            }

            foreach (var personUpdate in request.PersonUpdates)
            {
                using (var db = new BrennContext())
                {
                    using (var scope = new TransactionScope())
                    {
                        var person = db.People.Find(personUpdate.Person.PersonId);

                        if (person == null)
                        {
                            response.PersonUpdateResults.Add(
                                new UpdateResult { Error = UpdateError.DeletedOnServer, ClientRowId = personUpdate.Person.RowId });
                            continue;
                        }

                        if (person.RowId != personUpdate.ClientRowId)
                        {
                            response.PersonUpdateResults.Add(
                                new UpdateResult { Error = UpdateError.ModifiedOnServer, ClientRowId = personUpdate.Person.RowId });
                            continue;
                        }

                        var entry = db.Entry(person);
                        entry.CurrentValues.SetValues(personUpdate.Person);

                        db.SaveChanges();

                        scope.Complete();
                    }

                    response.PersonUpdateResults.Add(
                        new UpdateResult { Error = null, ClientRowId = personUpdate.Person.RowId });

                    updatedPersonIds.Add(personUpdate.Person.PersonId);
                }
            }
        }
예제 #3
0
파일: Brenn.svc.cs 프로젝트: abrkn/Brenn
        private static void PerformTripUpdates(
            SyncRequest request, SyncResponse response, ICollection<int> updatedTripIds)
        {
            if (request.TripUpdates == null)
            {
                return;
            }

            foreach (var tripUpdate in request.TripUpdates)
            {
                if (tripUpdate.ClientRowId == default(Guid))
                {
                    throw new Exception("The client row id must be set.");
                }

                using (var db = new BrennContext())
                {
                    using (var scope = new TransactionScope())
                    {
                        if (tripUpdate.Trip.TripId == default(int))
                        {
                            db.Trips.Add(tripUpdate.Trip);
                        }
                        else
                        {
                            var trip = db.Trips.Find(tripUpdate.Trip.TripId);

                            if (trip == null)
                            {
                                response.TripUpdateResults.Add(
                                    new UpdateResult
                                        {
                                            Error = UpdateError.DeletedOnServer, ClientRowId = tripUpdate.Trip.RowId
                                        });
                                continue;
                            }

                            if (trip.RowId != tripUpdate.ClientRowId)
                            {
                                response.TripUpdateResults.Add(
                                    new UpdateResult
                                        {
                                            Error = UpdateError.ModifiedOnServer, ClientRowId = tripUpdate.Trip.RowId
                                        });
                                continue;
                            }

                            var entry = db.Entry(trip);
                            entry.CurrentValues.SetValues(tripUpdate.Trip);
                        }

                        db.SaveChanges();

                        scope.Complete();
                    }

                    response.TripUpdateResults.Add(
                        new UpdateResult { Error = null, ClientRowId = tripUpdate.Trip.RowId });

                    updatedTripIds.Add(tripUpdate.Trip.TripId);
                }
            }
        }
예제 #4
0
파일: Brenn.svc.cs 프로젝트: abrkn/Brenn
        private static void PerformExpenseUpdates(
            SyncRequest request, SyncResponse response, List<int> updatedExpenseIds)
        {
            if (request.ExpenseUpdates == null)
            {
                return;
            }

            foreach (ExpenseUpdate expenseUpdate in request.ExpenseUpdates)
            {
                using (var db = new BrennContext())
                {
                    using (var scope = new TransactionScope())
                    {
                        var expense = db.Expenses.Find(expenseUpdate.Expense.ExpenseId);

                        if (expense == null)
                        {
                            response.ExpenseUpdateResults.Add(
                                new UpdateResult
                                    { Error = UpdateError.DeletedOnServer, ClientRowId = expenseUpdate.Expense.RowId });
                            continue;
                        }

                        if (expense.RowId != expenseUpdate.ClientRowId)
                        {
                            response.ExpenseUpdateResults.Add(
                                new UpdateResult
                                    { Error = UpdateError.ModifiedOnServer, ClientRowId = expenseUpdate.Expense.RowId });
                            continue;
                        }

                        var entry = db.Entry(expense);
                        entry.CurrentValues.SetValues(expenseUpdate.Expense);

                        db.SaveChanges();

                        scope.Complete();
                    }

                    response.ExpenseUpdateResults.Add(
                        new UpdateResult { Error = null, ClientRowId = expenseUpdate.Expense.RowId });

                    updatedExpenseIds.Add(expenseUpdate.Expense.ExpenseId);
                }
            }
        }