private boolean save ( Document document , boolean deletion , ConcurrencyControl concurrencyControl ) throws CouchbaseLiteException { if ( deletion && ! document . exists ( ) ) { throw new CouchbaseLiteException ( "Cannot delete a document that has not yet been saved." , CBLError . Domain . CBLITE , CBLError . Code . NOT_FOUND ) ; } C4Document curDoc = null ; C4Document newDoc = null ; synchronized ( lock ) { mustBeOpen ( ) ; prepareDocument ( document ) ; boolean commit = false ; beginTransaction ( ) ; try { try { newDoc = save ( document , null , deletion ) ; commit = true ; } catch ( LiteCoreException e ) { if ( ! ( e . domain == C4Constants . ErrorDomain . LITE_CORE && e . code == C4Constants . LiteCoreError . CONFLICT ) ) { throw CBLStatus . convertException ( e ) ; } } if ( newDoc == null ) { // Handle conflict: if ( concurrencyControl . equals ( ConcurrencyControl . FAIL_ON_CONFLICT ) ) { return false ; // document is conflicted and return false because of OPTIMISTIC } try { curDoc = getC4Database ( ) . get ( document . getId ( ) , true ) ; } catch ( LiteCoreException e ) { if ( deletion && e . domain == C4Constants . ErrorDomain . LITE_CORE && e . code == C4Constants . LiteCoreError . NOT_FOUND ) { return true ; } else { throw CBLStatus . convertException ( e ) ; } } if ( deletion && curDoc . deleted ( ) ) { document . replaceC4Document ( curDoc ) ; curDoc = null ; // NOTE: prevent to call curDoc.free() in finally block return true ; } // Save changes on the current branch: // NOTE: curDoc null check is done in prev try-catch blcok try { newDoc = save ( document , curDoc , deletion ) ; } catch ( LiteCoreException e ) { throw CBLStatus . convertException ( e ) ; } } document . replaceC4Document ( newDoc ) ; commit = true ; } finally { if ( curDoc != null ) { curDoc . retain ( ) ; curDoc . release ( ) ; // curDoc is not retained } try { endTransaction ( commit ) ; // true: commit the transaction, false: abort the transaction } catch ( CouchbaseLiteException e ) { if ( newDoc != null ) { newDoc . release ( ) ; // newDoc is already retained } throw e ; } } return true ; } }
The main save method .