@@ -1269,6 +1269,8 @@ public synchronized boolean open() {
12691269 "key BLOB NOT NULL, " +
12701270 "type TEXT, " +
12711271 "length INTEGER NOT NULL, " +
1272+ "encoding INTEGER DEFAULT 0, " +
1273+ "encoded_length INTEGER, " +
12721274 "revpos INTEGER DEFAULT 0); " +
12731275 "CREATE INDEX attachments_by_sequence on attachments(sequence, filename); " +
12741276 "CREATE INDEX attachments_sequence ON attachments(sequence); " +
@@ -1297,9 +1299,16 @@ public synchronized boolean open() {
12971299 int revPos = (Integer ) attachment .get ("revpos" );
12981300 int length = (Integer ) attachment .get ("length" );
12991301 String digest = (String ) attachment .get ("digest" );
1302+ int encodedLength = -1 ;
1303+ if (attachment .containsKey ("encoded_length" ))
1304+ encodedLength = (Integer )attachment .get ("encoded_length" );
1305+ AttachmentInternal .AttachmentEncoding encoding = AttachmentInternal .AttachmentEncoding .AttachmentEncodingNone ;
1306+ if (attachment .containsKey ("encoding" ) && attachment .get ("encoding" ).equals ("gzip" )){
1307+ encoding = AttachmentInternal .AttachmentEncoding .AttachmentEncodingGZIP ;
1308+ }
13001309 BlobKey key = new BlobKey (digest );
13011310 try {
1302- insertAttachmentForSequenceWithNameAndType (sequence , name , contentType , revPos , key , length );
1311+ insertAttachmentForSequenceWithNameAndType (sequence , name , contentType , revPos , key , length , encoding , encodedLength );
13031312 } catch (CouchbaseLiteException e ) {
13041313 Log .e (Log .TAG_DATABASE , "Attachment information inserstion error: " + name + "=" + attachment .toString (), e );
13051314 return false ;
@@ -2854,10 +2863,15 @@ void insertAttachmentForSequence(AttachmentInternal attachment, long sequence) t
28542863 attachment .getName (),
28552864 attachment .getContentType (),
28562865 attachment .getRevpos (),
2857- attachment .getBlobKey ());
2866+ attachment .getBlobKey (),
2867+ attachment .getLength (),
2868+ attachment .getEncoding (),
2869+ attachment .getEncodedLength ());
28582870 }
28592871
28602872 /**
2873+ * Note: This method is used only from unit tests.
2874+ *
28612875 * @exclude
28622876 */
28632877 @ InterfaceAudience .Private
@@ -2882,37 +2896,28 @@ public void insertAttachmentForSequenceWithNameAndType(InputStream contentStream
28822896 */
28832897 @ InterfaceAudience .Private
28842898 public void insertAttachmentForSequenceWithNameAndType (long sequence , String name , String contentType , int revpos , BlobKey key ) throws CouchbaseLiteException {
2885- try {
2886- ContentValues args = new ContentValues ();
2887- args .put ("sequence" , sequence );
2888- args .put ("filename" , name );
2889- if (key != null ) {
2890- args .put ("key" , key .getBytes ());
2891- args .put ("length" , attachments .getSizeOfBlob (key ));
2892- }
2893- args .put ("type" , contentType );
2894- args .put ("revpos" , revpos );
2895- long result = database .insert ("attachments" , null , args );
2896- if (result == -1 ) {
2897- String msg = "Insert attachment failed (returned -1)" ;
2898- Log .e (Database .TAG , msg );
2899- throw new CouchbaseLiteException (msg , Status .INTERNAL_SERVER_ERROR );
2900- }
2901- } catch (SQLException e ) {
2902- Log .e (Database .TAG , "Error inserting attachment" , e );
2903- throw new CouchbaseLiteException (e , Status .INTERNAL_SERVER_ERROR );
2904- }
2899+ insertAttachmentForSequenceWithNameAndType (sequence , name , contentType , revpos , key , key != null ? attachments .getSizeOfBlob (key ): -1 , AttachmentInternal .AttachmentEncoding .AttachmentEncodingNone , -1 );
29052900 }
29062901
2907- private void insertAttachmentForSequenceWithNameAndType (long sequence , String name , String contentType , int revpos , BlobKey key , long length ) throws CouchbaseLiteException {
2902+ private void insertAttachmentForSequenceWithNameAndType (long sequence , String name , String contentType , int revpos , BlobKey key , long length , AttachmentInternal . AttachmentEncoding encoding , long encodedLength ) throws CouchbaseLiteException {
29082903 try {
29092904 ContentValues args = new ContentValues ();
29102905 args .put ("sequence" , sequence );
29112906 args .put ("filename" , name );
2912- args .put ("key" , key .getBytes ());
2913- args .put ("length" , length );
29142907 args .put ("type" , contentType );
29152908 args .put ("revpos" , revpos );
2909+ if (key != null ) {
2910+ args .put ("key" , key .getBytes ());
2911+ }
2912+ if (length >= 0 ) {
2913+ args .put ("length" , length );
2914+ }
2915+ if (encoding == AttachmentInternal .AttachmentEncoding .AttachmentEncodingGZIP ) {
2916+ args .put ("encoding" , encoding .ordinal ());
2917+ if (encodedLength >= 0 ) {
2918+ args .put ("encoded_length" , encodedLength );
2919+ }
2920+ }
29162921 long result = database .insert ("attachments" , null , args );
29172922 if (result == -1 ) {
29182923 String msg = "Insert attachment failed (returned -1)" ;
@@ -2924,6 +2929,7 @@ private void insertAttachmentForSequenceWithNameAndType(long sequence, String na
29242929 throw new CouchbaseLiteException (e , Status .INTERNAL_SERVER_ERROR );
29252930 }
29262931 }
2932+
29272933 /**
29282934 * @exclude
29292935 */
@@ -3116,7 +3122,7 @@ public Map<String,Object> getAttachmentsDictForSequenceWithContent(long sequence
31163122
31173123 String args [] = { Long .toString (sequence ) };
31183124 try {
3119- cursor = database .rawQuery ("SELECT filename, key, type, length, revpos FROM attachments WHERE sequence=?" , args );
3125+ cursor = database .rawQuery ("SELECT filename, key, type, encoding, length, encoded_length , revpos FROM attachments WHERE sequence=?" , args );
31203126
31213127 if (!cursor .moveToNext ()) {
31223128 return null ;
@@ -3127,7 +3133,10 @@ public Map<String,Object> getAttachmentsDictForSequenceWithContent(long sequence
31273133 while (!cursor .isAfterLast ()) {
31283134
31293135 boolean dataSuppressed = false ;
3130- int length = cursor .getInt (3 );
3136+ int length = cursor .getInt (4 );
3137+
3138+ AttachmentInternal .AttachmentEncoding encoding = AttachmentInternal .AttachmentEncoding .values ()[cursor .getInt (3 )];
3139+ int encodedLength = cursor .getInt (5 );
31313140
31323141 byte [] keyData = cursor .getBlob (1 );
31333142 BlobKey key = new BlobKey (keyData );
@@ -3140,39 +3149,40 @@ public Map<String,Object> getAttachmentsDictForSequenceWithContent(long sequence
31403149 }
31413150 else {
31423151 byte [] data = attachments .blobForKey (key );
3143-
31443152 if (data != null ) {
31453153 dataBase64 = Base64 .encodeBytes (data ); // <-- very expensive
31463154 }
31473155 else {
31483156 Log .w (Database .TAG , "Error loading attachment. Sequence: %s" , sequence );
31493157 }
3150-
31513158 }
3159+ }
31523160
3161+ String encodingStr = null ;
3162+ if (encoding !=AttachmentInternal .AttachmentEncoding .AttachmentEncodingNone ){
3163+ // NOTE: iOS decode if attachment is included int the dict.
3164+ encodingStr = "gzip" ;
31533165 }
31543166
31553167 Map <String , Object > attachment = new HashMap <String , Object >();
3156-
3157-
3158-
31593168 if (!(dataBase64 != null || dataSuppressed )) {
31603169 attachment .put ("stub" , true );
31613170 }
3162-
31633171 if (dataBase64 != null ) {
31643172 attachment .put ("data" , dataBase64 );
31653173 }
3166-
31673174 if (dataSuppressed == true ) {
31683175 attachment .put ("follows" , true );
31693176 }
3170-
31713177 attachment .put ("digest" , digestString );
31723178 String contentType = cursor .getString (2 );
31733179 attachment .put ("content_type" , contentType );
3180+ if (encodingStr != null )
3181+ attachment .put ("encoding" , encodingStr );
31743182 attachment .put ("length" , length );
3175- attachment .put ("revpos" , cursor .getInt (4 ));
3183+ if (encodingStr != null && encodedLength >= 0 )
3184+ attachment .put ("encoded_length" , encodedLength );
3185+ attachment .put ("revpos" , cursor .getInt (6 ));
31763186
31773187 String filename = cursor .getString (0 );
31783188 result .put (filename , attachment );
@@ -4262,7 +4272,7 @@ Map<String, AttachmentInternal> getAttachmentsFromRevision(RevisionInternal rev,
42624272 // If there's inline attachment data, decode and store it:
42634273 byte [] newContents ;
42644274 try {
4265- newContents = Base64 .decode (newContentBase64 );
4275+ newContents = Base64 .decode (newContentBase64 , Base64 . DONT_GUNZIP );
42664276 } catch (IOException e ) {
42674277 throw new CouchbaseLiteException (e , Status .BAD_ENCODING );
42684278 }
0 commit comments