Ejemplo n.º 1
0
            private void AddAttachmentsToSequence(long sequence, List <byte> json)
            {
                // CREATE TABLE attachments (
                //  sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE,
                //  filename TEXT NOT NULL,
                //  key BLOB NOT NULL,
                //  type TEXT,
                //  length INTEGER NOT NULL,
                //  revpos INTEGER DEFAULT 0,
                //  encoding INTEGER DEFAULT 0,
                //  encoded_length INTEGER );
                sqlite3_stmt attQuery = null;

                try {
                    PrepareSQL(ref attQuery, "SELECT filename, key, type, length,"
                               + " revpos, encoding, encoded_length FROM attachments WHERE sequence=?");
                } catch (CouchbaseLiteException) {
                    Log.To.Upgrade.E(TAG, "Failed to create SQLite query for attachments table in " +
                                     "source database '{0}', rethrowing...", _path);
                    throw;
                } catch (Exception e) {
                    throw Misc.CreateExceptionAndLog(Log.To.Upgrade, e, TAG,
                                                     "Error creating SQLite query for attachments table in source database '{0}'", _path);
                }

                raw.sqlite3_bind_int64(attQuery, 1, sequence);

                var attachments = new Dictionary <string, object>();

                int err;

                while (raw.SQLITE_ROW == (err = raw.sqlite3_step(attQuery)))
                {
                    string name          = raw.sqlite3_column_text(attQuery, 0);
                    var    key           = raw.sqlite3_column_blob(attQuery, 1);
                    string mimeType      = raw.sqlite3_column_text(attQuery, 2);
                    long   length        = raw.sqlite3_column_int64(attQuery, 3);
                    int    revpos        = raw.sqlite3_column_int(attQuery, 4);
                    int    encoding      = raw.sqlite3_column_int(attQuery, 5);
                    long   encodedLength = raw.sqlite3_column_int64(attQuery, 6);

                    if (key.Length != SHA1.Create().HashSize / 8)
                    {
                        raw.sqlite3_finalize(attQuery);
                        throw Misc.CreateExceptionAndLog(Log.To.Upgrade, StatusCode.CorruptError, TAG,
                                                         "Digest key length incorrect ({0})", Convert.ToBase64String(key));
                    }

                    var blobKey = new BlobKey(key);
                    var att     = new NonNullDictionary <string, object> {
                        { "type", mimeType },
                        { "digest", blobKey.Base64Digest() },
                        { "length", length },
                        { "revpos", revpos },
                        { "follows", true },
                        { "encoding", encoding != 0 ? "gzip" : null },
                        { "encoded_length", encoding != 0 ? (object)encodedLength : null }
                    };

                    attachments[name] = att;
                }

                raw.sqlite3_finalize(attQuery);
                if (err != raw.SQLITE_DONE)
                {
                    throw Misc.CreateExceptionAndLog(Log.To.Upgrade, SqliteErrToStatus(err).Code, TAG,
                                                     "Failed to finalize attachment query ({0}: {1})", err, raw.sqlite3_errmsg(_sqlite));
                }

                if (attachments.Count > 0)
                {
                    // Splice attachment JSON into the document JSON:
                    var attJson = Manager.GetObjectMapper().WriteValueAsBytes(new Dictionary <string, object> {
                        { "_attachments", attachments }
                    });

                    if (json.Count > 2)
                    {
                        json.Insert(json.Count - 1, (byte)',');
                    }

                    json.InsertRange(json.Count - 1, attJson.Skip(1).Take(attJson.Count() - 2));
                }
            }
            private void AddAttachmentsToSequence(long sequence, List<byte> json)
            {
                // CREATE TABLE attachments (
                //  sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE,
                //  filename TEXT NOT NULL,
                //  key BLOB NOT NULL,
                //  type TEXT,
                //  length INTEGER NOT NULL,
                //  revpos INTEGER DEFAULT 0,
                //  encoding INTEGER DEFAULT 0,
                //  encoded_length INTEGER );
                sqlite3_stmt attQuery = null;
                try {
                    PrepareSQL(ref attQuery, "SELECT filename, key, type, length,"
                                + " revpos, encoding, encoded_length FROM attachments WHERE sequence=?");
                } catch(CouchbaseLiteException) {
                    Log.W(TAG, "Failed to create SQLite query for attachments table in source database '{0}'", _path);
                    throw;
                } catch(Exception e) {
                    throw new CouchbaseLiteException(String.Format(
                        "Error creating SQLite query for attachments table in source database '{0}'", _path),
                        e) { Code = StatusCode.DbError };
                }

                raw.sqlite3_bind_int64(attQuery, 1, sequence);

                var attachments = new Dictionary<string, object>();

                int err;
                while (raw.SQLITE_ROW == (err = raw.sqlite3_step(attQuery))) {
                    string name = raw.sqlite3_column_text(attQuery, 0);
                    var key = raw.sqlite3_column_blob(attQuery, 1);
                    string mimeType = raw.sqlite3_column_text(attQuery, 2);
                    long length = raw.sqlite3_column_int64(attQuery, 3);
                    int revpos = raw.sqlite3_column_int(attQuery, 4);
                    int encoding = raw.sqlite3_column_int(attQuery, 5);
                    long encodedLength = raw.sqlite3_column_int64(attQuery, 6);

                    if (key.Length != SHA1.Create().HashSize / 8) {
                        raw.sqlite3_finalize(attQuery);
                        throw new CouchbaseLiteException(String.Format(
                            "Digest key length incorrect ({0})", Convert.ToBase64String(key)), StatusCode.CorruptError);
                    }

                    var blobKey = new BlobKey(key);
                    var att = new NonNullDictionary<string, object> {
                        { "type", mimeType },
                        { "digest", blobKey.Base64Digest() },
                        { "length", length },
                        { "revpos", revpos },
                        { "follows", true },
                        { "encoding", encoding != 0 ? "gzip" : null },
                        { "encoded_length", encoding != 0 ? (object)encodedLength : null }
                    };

                    attachments[name] = att;
                }

                raw.sqlite3_finalize(attQuery);
                if (err != raw.SQLITE_DONE) {
                    throw new CouchbaseLiteException(String.Format(
                        "Failed to finalize attachment query ({0}: {1})", err, raw.sqlite3_errmsg(_sqlite)),
                        SqliteErrToStatus(err).Code);
                }

                if (attachments.Count > 0) {
                    // Splice attachment JSON into the document JSON:
                    var attJson = Manager.GetObjectMapper().WriteValueAsBytes(new Dictionary<string, object> { { "_attachments", attachments } });

                    if (json.Count > 2) {
                        json.Insert(json.Count - 1, (byte)',');
                    }

                    json.InsertRange(json.Count - 1, attJson.Skip(1).Take(attJson.Count() - 2));
                }
            }
            private Status AddAttachmentsToSequence(long sequence, List <byte> json)
            {
                // CREATE TABLE attachments (
                //  sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE,
                //  filename TEXT NOT NULL,
                //  key BLOB NOT NULL,
                //  type TEXT,
                //  length INTEGER NOT NULL,
                //  revpos INTEGER DEFAULT 0,
                //  encoding INTEGER DEFAULT 0,
                //  encoded_length INTEGER );
                sqlite3_stmt attQuery = null;
                Status       status   = PrepareSQL(ref attQuery, "SELECT filename, key, type, length,"
                                                   + " revpos, encoding, encoded_length FROM attachments WHERE sequence=?");

                if (status.IsError)
                {
                    return(status);
                }

                raw.sqlite3_bind_int64(attQuery, 1, sequence);

                var attachments = new Dictionary <string, object>();

                int err;

                while (raw.SQLITE_ROW == (err = raw.sqlite3_step(attQuery)))
                {
                    string name          = raw.sqlite3_column_text(attQuery, 0);
                    var    key           = raw.sqlite3_column_blob(attQuery, 1);
                    string mimeType      = raw.sqlite3_column_text(attQuery, 2);
                    long   length        = raw.sqlite3_column_int64(attQuery, 3);
                    int    revpos        = raw.sqlite3_column_int(attQuery, 4);
                    int    encoding      = raw.sqlite3_column_int(attQuery, 5);
                    long   encodedLength = raw.sqlite3_column_int64(attQuery, 6);

                    if (key.Length != SHA1.Create().HashSize / 8)
                    {
                        raw.sqlite3_finalize(attQuery);
                        return(new Status(StatusCode.CorruptError));
                    }

                    var blobKey = new BlobKey(key);
                    var att     = new NonNullDictionary <string, object> {
                        { "type", mimeType },
                        { "digest", blobKey.Base64Digest() },
                        { "length", length },
                        { "revpos", revpos },
                        { "follows", true },
                        { "encoding", encoding != 0 ? "gzip" : null },
                        { "encoded_length", encoding != 0 ? (object)encodedLength : null }
                    };

                    attachments[name] = att;
                }

                raw.sqlite3_finalize(attQuery);
                if (err != raw.SQLITE_DONE)
                {
                    return(SqliteErrToStatus(err));
                }

                if (attachments.Count > 0)
                {
                    // Splice attachment JSON into the document JSON:
                    var attJson = Manager.GetObjectMapper().WriteValueAsBytes(new Dictionary <string, object> {
                        { "_attachments", attachments }
                    });

                    if (json.Count > 2)
                    {
                        json.Insert(json.Count - 1, (byte)',');
                    }

                    json.InsertRange(json.Count - 1, attJson.Skip(1).Take(attJson.Count() - 2));
                }

                return(new Status(StatusCode.Ok));
            }
            private Status AddAttachmentsToSequence(long sequence, List<byte> json)
            {
                // CREATE TABLE attachments (
                //  sequence INTEGER NOT NULL REFERENCES revs(sequence) ON DELETE CASCADE,
                //  filename TEXT NOT NULL,
                //  key BLOB NOT NULL,
                //  type TEXT,
                //  length INTEGER NOT NULL,
                //  revpos INTEGER DEFAULT 0,
                //  encoding INTEGER DEFAULT 0,
                //  encoded_length INTEGER );
                sqlite3_stmt attQuery = null;
                Status status = PrepareSQL(ref attQuery, "SELECT filename, key, type, length,"
                                + " revpos, encoding, encoded_length FROM attachments WHERE sequence=?");
                if (status.IsError) {
                    return status;
                }

                raw.sqlite3_bind_int64(attQuery, 1, sequence);

                var attachments = new Dictionary<string, object>();

                int err;
                while (raw.SQLITE_ROW == (err = raw.sqlite3_step(attQuery))) {
                    string name = raw.sqlite3_column_text(attQuery, 0);
                    var key = raw.sqlite3_column_blob(attQuery, 1);
                    string mimeType = raw.sqlite3_column_text(attQuery, 2);
                    long length = raw.sqlite3_column_int64(attQuery, 3);
                    int revpos = raw.sqlite3_column_int(attQuery, 4);
                    int encoding = raw.sqlite3_column_int(attQuery, 5);
                    long encodedLength = raw.sqlite3_column_int64(attQuery, 6);

                    if (key.Length != SHA1.Create().HashSize / 8) {
                        raw.sqlite3_finalize(attQuery);
                        return new Status(StatusCode.CorruptError);
                    }

                    var blobKey = new BlobKey(key);
                    var att = new NonNullDictionary<string, object> {
                        { "type", mimeType },
                        { "digest", blobKey.Base64Digest() },
                        { "length", length },
                        { "revpos", revpos },
                        { "follows", true },
                        { "encoding", encoding != 0 ? "gzip" : null },
                        { "encoded_length", encoding != 0 ? (object)encodedLength : null }
                    };

                    attachments[name] = att;
                }

                raw.sqlite3_finalize(attQuery);
                if (err != raw.SQLITE_DONE) {
                    return SqliteErrToStatus(err);
                }

                if (attachments.Count > 0) {
                    // Splice attachment JSON into the document JSON:
                    var attJson = Manager.GetObjectMapper().WriteValueAsBytes(new Dictionary<string, object> { { "_attachments", attachments } });

                    if (json.Count > 2) {
                        json.Insert(json.Count - 1, (byte)',');
                    }

                    json.InsertRange(json.Count - 1, attJson.Skip(1).Take(attJson.Count() - 2));
                }

                return new Status(StatusCode.Ok);
            }