2015-06-23 3 views
7

SaveAllInBackground non funziona all'interno di deleteAllInBackground come desiderato.SaveAllInBackground non funziona all'interno di deleteAllInBackground come desiderato

Sto tentando di salvare un elenco di parseobjects usando save all in background. Per evitare duplicati nella tabella, sto interrogando per le righe già esistenti e cancellandole se ce ne sono e quindi salvando la nuova copia. Pertanto sto chiamando saveAllInBackground all'interno del callback di deleteAllInBackground.

Il problema è questo:

Per esempio: se la lista per eliminare contiene [a, b, c, d] e la lista di caricare ha [a, b, c, d, e, f] solo [e, f] vengono persi in analisi. Sto passando [a, b, c, d, e, f] al saveAllInBackground ma solo [e, f] viene mantenuto.

  • C'è qualcosa che mi manca? Come risolvere questo?

  • Posso utilizzare un approccio diverso?

  • Esiste un modo migliore per evitare i duplicati? Non voglio aggiungere un hook prima del salvataggio . L'intero scopo di chiamare saveAll è ridurre il numero di chiamate API. Suppongo che se uso beforeSave, dovrò comunque eseguire alcune query nel codice cloud.

Questo è il mio codice

  ParseQuery query = new ParseQuery("PostChoice"); 

      query.fromPin(); 
      query.findInBackground(new FindCallback<ParseObject>() { 
       @Override 
       public void done(final List<ParseObject> localList, ParseException e) { 
        if (localList != null && !localList.isEmpty()) { 
         List<ParseObject> postList = new ArrayList<ParseObject>(); 
         for (ParseObject object : localList) { 

          postList.add(object.getParseObject("post")); 
         } 
         ParseQuery query = new ParseQuery("PostChoice"); 
         query.whereContainedIn("post", postList); 
         query.whereEqualTo("user", ParseUser.getCurrentUser()); 
         query.findInBackground(new FindCallback<ParseObject>() { 
          @Override 
          public void done(List<ParseObject> parseCloudList, ParseException e) { 

           if (parseCloudList != null && !parseCloudList.isEmpty()) { 
            ParseObject.deleteAllInBackground(parseCloudList, new DeleteCallback() { 
             @Override 
             public void done(ParseException e) { 
       // this gets executed and rows are accordingly deleted        
              ParseObject.saveAllInBackground(localList, new SaveCallback() { 
               @Override 
               public void done(ParseException e) { 
// this gets executed but the rows are not uploaded. 
//the locallist is not empty. it contains the right data. 
                editor.putLong(Four.LAST_CHOICE_SYNC_TIME, System.currentTimeMillis()); 
                editor.commit(); 
                Log.i("SyncChoiceService", "Synced Choices"); 
               } 
              }); 
             } 
            }); 
           } 
           else{ 
            ParseObject.saveAllInBackground(localList, new SaveCallback() { 
             @Override 
             public void done(ParseException e) { 
              Log.i("SyncChoiceService", "Synced Choices"); 
              editor.putLong(Four.LAST_CHOICE_SYNC_TIME,System.currentTimeMillis()); 
              editor.commit(); 
             } 
            }); 
           } 
          } 
         }); 


        } 
       } 
      }); 

risposta

1

Sono venuto su con una soluzione di questo tipo. e soddisfa le mie esigenze. Io uso il valore aggiornato ed elimina quelli vecchi e il resto viene aggiornato come un intero elenco.

ParseQuery query = new ParseQuery("PostChoice"); 

      query.fromPin(); 
      query.findInBackground(new FindCallback<ParseObject>() { 
       @Override 
       public void done(final List<ParseObject> localList, ParseException e) { 
        if (localList != null && !localList.isEmpty()) { 

         List<ParseObject> postList = new ArrayList<ParseObject>(); 
         for (ParseObject object : localList) { 

          postList.add(object.getParseObject("post")); 
         } 
         ParseQuery query = new ParseQuery("PostChoice"); 
         query.whereContainedIn("post", postList); 
         query.whereLessThan("updatedAt",System.currentTimeMillis()); 
         query.whereEqualTo("user", ParseUser.getCurrentUser()); 
         query.findInBackground(new FindCallback<ParseObject>() { 
          @Override 
          public void done(final List<ParseObject> parseCloudList, ParseException e) { 
           if (parseCloudList != null && !parseCloudList.isEmpty()) { 
            ParseObject.deleteAllInBackground(parseCloudList, new DeleteCallback() { 
             @Override 
             public void done(ParseException e) { 
              Log.i("SyncChoiceService", "Deleted old Choices"); 

             } 
            }); 
           } 


            } 
           }); 


ParseObject.saveAllInBackground(localList, new SaveCallback() { 
     @Override 
     public void done(ParseException e) { 
      Log.i("SyncChoiceService", "Synced Choices"); 
     } 
    }); 

        } 
       } 
      }); 
-1

Sì, se ho capito bene si desidera salvare solo i nuovi dati da LocalDB da analizzare backend.

La soluzione migliore e meno richiesta sarebbe quella di avere un altro campo nella tabella chiamato "Bozza" o "Aggiornato" (nome come desiderato). Il ruolo di questo flag è identificare se questo campo è stato salvato nel back-end o meno. se è un nuovo campo "isUpdated" è falso, è vero. Quindi nella query è possibile eseguire query solo su isUpdated è false. Quindi salvali nel back-end. Then

  1. Non si desidera eliminare alcun dato.
  2. Riduci le richieste
  3. Meno logica inutile nel codice.
  4. è pulito

Spero che questo aiuti

+0

Non possiamo farlo senza una bandiera? le bandiere a lungo termine diventano un overhead. Preferisco mantenere le colonne al minimo e gestire la logica nel codice. – 55597

+0

Questo è il metodo che userei, a causa di ragioni citate. Ma i costi dei miei punti di reputazione preferirei non aiutarti. –