Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Update doc with existing attachment #101

Closed
bardu opened this Issue Sep 12, 2012 · 25 comments

Comments

Projects
None yet
2 participants

bardu commented Sep 12, 2012

What is right approach to update a doc with an existing attachment?

I write the attachment (image) to a file, then update the doc by inserting and then read the image file to insert the attachment.

Here is my code https://gist.github.com/3707656

However, inserting the attachment fails with 409. I can assure that the right doc._id and doc._rev is supplied, but have no idea where the conflict comes from.

Is there a better way to do that?

Owner

dscape commented Sep 12, 2012

Hi @bardu

Check this out, should be enough to fix your problem:

Ditch the old code and start off based on this.

Nuno

@dscape dscape closed this Sep 12, 2012

bardu commented Sep 12, 2012

Thanks, but don't get the point.

My problem is not to update an attachment, but doc fields in a doc that has an attachment.

Owner

dscape commented Sep 12, 2012

You said

inserting the attachment fails with 409.

Anyway can you tell me what is the objective of all this code here? I can give you a solution for it if I understand what you are trying to solve.

There's no issue on nano regarding this, hence I closed the issue.

bardu commented Sep 12, 2012

I have a db with docs that might have or not an image as an attachment.

case 1:
When a user wants to update the doc that has no attachment, an other module function takes care for this - no problem.

case 2:
When a user wants to update the image attachment of a doc, there is another module function - no problem.

case 3: (that's my issue)
A user wants to update one or more doc fields of a doc that has an image attachment, without providing the image again.

Could I explain my problem understandable?

Owner

dscape commented Sep 12, 2012

You don't need to re-add the image. Get the document, do the updates, update the document.

Ignore the fact that you have an attachment

Owner

dscape commented Sep 12, 2012

Does this work for you?

bardu commented Sep 12, 2012

I properly do the updates wrong, this is my code:

// update deal with no image
exports.updateDeal = function(req, res) {
    db.insert(req.body, req.params.id, function(err, doc) {
        if (err) {
            console.log('Update deal: ' + err.message + '   ' + err['status-code']);
            res.send(err['status-code']);
        }
        else {
            res.send({success: true});
        }
    });
};

After that the attachment is gone.

Owner

dscape commented Sep 12, 2012

What is req.body? Is that a result of a db.get ?

Doesn't look like it by looking at req.params.id

bardu commented Sep 12, 2012

I'm using express, that where the req.body comes from and on the client side backbone that send JSON.

bardu commented Sep 12, 2012

I believe I have tried with _attachment too, with them same result. But will give it another try.

Owner

dscape commented Sep 12, 2012

Not the attachment itself, but the attachment metadata.

It has to work, this is how CouchDB work.

It seems like complexity from backbone and express is what's eating you here, not couchdb/nano :)

Let me know if you need moar halp

bardu commented Sep 12, 2012

Yes, but if I add the attachment meta data to PUT

db.insert(req.body, req.params.id, function(err, doc) {...) throws

Unspecified error 500

To verify that the req.body object is correct, please have a look at this partial screen shot:

http://www.flickr.com/photos/52099104@N06/7980190323/in/photostream

bardu commented Sep 12, 2012

And this is from the couchdb log: https://gist.github.com/3708903

Owner

dscape commented Sep 12, 2012

Check 3a8e86b for a working example.

Maybe your CouchDB is outdate and that is a bug

bardu commented Sep 12, 2012

CouchDB version 1.2, I think that is the latest?

Owner

dscape commented Sep 12, 2012

@bardu just copy the code from the test, it does what you said couldnt be done

Also run the test suite localy with npm run nock_off

Nuno

bardu commented Sep 12, 2012

Nuno, I'm not familiar with specify, where should I put the test in my app? What are the dependencies?

Stephan

Owner

dscape commented Sep 12, 2012

Specify is something that runs tests sequentially.

Let me get you some code.

Owner

dscape commented Sep 12, 2012

Something like

var nano   = require("nano")
  , db     = nano("http://localhost:5984/foo")
  , pixel  = "R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
  , buf    = new Buffer(pixel, "base64")
  , rev
  ;

db.attachment.insert("bar", "p.gif", buf, "image/gif", function (error, bar_doc) {
  db.get("bar", function (error, from_couch) {
    from_couch.works = true;
    db.insert(from_couch, "bar", function (error, response) {
      console.log("done");
    });
  });
});
Owner

dscape commented Sep 12, 2012

In a real app I wouldnt go gung-oh nesting things. Each thing would be a function, and I would feed that to the callback

bardu commented Sep 12, 2012

Thanks Nuno for you time and code. I can confirm that your code runs through on both my local and IrisCouch couch.

I guess I have to go back to my request object to find the source of the problem.

Owner

dscape commented Sep 12, 2012

Sorry I can't help you more, but yeah maybe try to reduce complexity of your app if your frameworks are actually taking more time to figure out than to use plain vanilla nodejs!

bardu commented Sep 12, 2012

Just a final note:

Thanks to your test code I could solve my issue by following your pattern.

Instead of supplying the req.body object to db.insert() I first get the doc from the couch, change the doc.fields with the individual req.body values and then insert the changed doc. This way the attachments stay untouched.

Thanks again for your great support.

Owner

dscape commented Sep 12, 2012

You're welcome.

Enjoy node and couch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment