Не знаю, как добавить запись, если она не существует jaydata sqllite

Я пытаюсь выполнить следующую задачу. У меня есть массив json, возвращенный из удаленной базы данных, и я хочу перебрать его, проверить, существует ли запись с идентификатором объекта в локальной базе данных. Если существует, я хочу обновить запись, если нет, я хочу ее прикрепить. Код выглядит следующим образом:

$.each(data, function(idx, task) { 
                        var taskToUpdate = $org.context.Task.attachOrGet({ Id:task.TaskId});                        
                        taskToUpdate.TaskType = task.TaskType;
                        taskToUpdate.StatusId = task.TaskStatusId;
                        taskToUpdate.TaskStatus = task.TaskStatus;
                        taskToUpdate.DateScheduled = task.Date;
                        taskToUpdate.TimeSlot = task.Time;
                        taskToUpdate.LastUpdated = new Date();
                        taskToUpdate.TaskName = "Job " + task.TaskId + " " + task.TaskType + " @" + task.AddressOfTask + ", " + task.PropertyPostCode;
                        taskToUpdate.SpecialInstructions = task.SpecialInstructions;
                        taskToUpdate.PropertyAddress = task.AddressOfTask;
                        taskToUpdate.PropertyPostCode = task.PropertyPostCode;
                        taskToUpdate.PropertyType = task.PropertyType;
                        taskToUpdate.NumberOfBedrooms = task.NumberOfBedrooms;
                        taskToUpdate.HasGarage = task.HasGarage;
                        taskToUpdate.HasOutHouse = task.HasOutHouse;


                    });

                    $org.context.saveChanges({
                        success: function(db) {
                            that.messages.push("Tasks saved to local device.");
                        }, error: function(err) {
                            console.log(err);
                            that.messages.push("Errors saving tasks: " + err);
                            navigator.notification.alert("Error saving local tasks to your device!",
                                                         function () {
                                                         }, "Error", 'OK');
                        }
                    });  

Код выполняется успешно, но записи в таблицу задач не добавляются.

Я что-то упускаю?


person Dave Stringer    schedule 24.09.2013    source источник


Ответы (2)


Я пошел с этим кодом, который, кажется, работает, но просто не кажется «правильным». А именно, как я определяю, завершены ли обновления, чтобы избежать вызова context.savechanges() более одного. Пожалуйста, не стесняйтесь улучшить мой ответ!

function downloadTasksFromWeb(viewModel){
    $org.context.UserSetting.first().then(function (userSetting) {
                viewModel.set("currentUserSettings", userSetting);          

                backofficeUrl = viewModel.get("currentUserSettings.BackOfficeUrl") + "/api/tasks";
                var operatorId = viewModel.get("currentUserSettings.OperatorId");

                var rowsToProcess = 0, rowsProcessed = 0;

                viewModel.messages.push("Connecting to server.");
                showNotificationInfo("Connecting to server.");

                jQuery.ajax({
                    type: "GET",
                    url: backofficeUrl,
                    dataType: 'json',
                    async: false,
                    username: "user",
                    password: "pw",
                    data: {"operatorId": operatorId},
                    success: function (data) {
                        viewModel.messages.push("Tasks received, saving to local device.");
                        showNotificationInfo("Tasks received, saving to local device.");
                        rowsToProcess = data.length;
                        $.each(data, function(idx, task) { 
                            var existingTasks = $org.context.Task.filter("Id", "==", task.TaskId).toArray();

                            existingTasks.then(function(result) {
                                var taskToUpdate = $org.context.Task.attachOrGet({ Id:task.TaskId});

                                taskToUpdate.TaskType = task.TaskType;
                                taskToUpdate.StatusId = task.TaskStatusId;
                                taskToUpdate.TaskStatus = task.TaskStatus;
                                taskToUpdate.DateScheduled = task.Date;
                                taskToUpdate.TimeSlot = task.Time;
                                taskToUpdate.LastUpdated = new Date();
                                taskToUpdate.TaskName = "Job " + task.TaskId + " " + task.TaskType + " @" + task.AddressOfTask + ", " + task.PropertyPostCode;
                                taskToUpdate.SpecialInstructions = task.SpecialInstructions;
                                taskToUpdate.PropertyAddress = task.AddressOfTask;
                                taskToUpdate.PropertyPostCode = task.PropertyPostCode;
                                taskToUpdate.PropertyType = task.PropertyType;
                                taskToUpdate.NumberOfBedrooms = task.NumberOfBedrooms;
                                taskToUpdate.HasGarage = task.HasGarage;
                                taskToUpdate.HasOutHouse = task.HasOutHouse;

                                if (result.length == 0) {
                                    $org.context.Task.add(taskToUpdate);
                                }

                                rowsProcessed++;

                                if (rowsProcessed == rowsToProcess) {
                                    $org.context.saveChanges({
                                        success: function(db) {
                                            viewModel.messages.push("Tasks saved to local device.");
                                            showNotificationInfo("Tasks saved to local device.");
                                        }, error: function(err) {
                                            console.log(err);
                                            viewModel.messages.push("Errors saving tasks: " + err);
                                            showNotificationError("Errors saving tasks: " + err);                                            
                                        }
                                    });  
                                }
                            });
                        });
                    }
                }).fail(function(resultData) {
                    showNotificationError("There was an error communicating with the server.  Please check your settings and try again.");

                });
            });
} 
person Dave Stringer    schedule 26.09.2013
comment
Jaydata основан на промисах, поэтому вы можете легко использовать отложенные Q или jQuery. jaydata.org/blog/ - person George Antoniadis; 22.02.2014

Вместо $.each вам нужна рекурсивная функция со следующим алгоритмом: - проверить, есть ли запись, сохраненная в локальной БД с определенным идентификатором

  • if yes
    • attach
    • установить свойства
  • if no
    • create a new typed element entity
    • установить свойства
    • добавить объект в коллекцию - context.Tasks.add(newEntity)
  • После завершения всего вашего кода вызовите context.saveChanges(), чтобы сохранить все изменения в пакете. Это намного быстрее и безопаснее, чем ваш код, вызывающий saveChanes() внутри foreach.

Рекурсивная функция необходима из-за асинхронного поведения.

person Robesz    schedule 25.09.2013
comment
Спасибо за ответ, извините, я не ясно выразился, данные поступают с удаленного сервера, поэтому сохранение изменений вне поля зрения. Однако реальная проблема заключается в том, что в jaydata нет простой функции, если строка существует, поэтому я заранее не знаю, новая она или существует. Должен ли я использовать простой filter.count(), чтобы проверить, есть ли уже строка? - person Dave Stringer; 25.09.2013
comment
Да, вы можете использовать count() или length() context.Tasks.filter('it.Task_ID == 140').count(function(count) {console.log(count)}); - person Robesz; 26.09.2013
comment
Спасибо. Кажется, что Count выдает ошибку, если строки нет, и, хотя люди из jaydata говорят, что вы можете ее игнорировать, неприятно видеть ошибки в журнале консоли ... Я применил подход в своем ответе ниже ... Это не идеально, но, кажется, работает... что вы думаете? - person Dave Stringer; 26.09.2013
comment
В журнале консоли не должно быть ошибки, я только что проверил ее с помощью поставщиков WebSQL, IndexedDB, localStore и OData. Поделитесь своим кодом, я проверю. - person Robesz; 26.09.2013