Issue with CouchDB - couchdb

In the TAMA implementation, I came across an issue with Couchdb. (Version 1.2.0) ,
We are using named documents to maintain unique constraint logic in the application. (named documents : whose _id is user defined, and not couch generated.)
We are using the REST API to add the documents to Couchdb, where we found strange behavior :
When we try to recreate the documents using HTTP PUT which have been deleted in the past(because of bug in the code), the documents are not created the first time .
HTTP Put - Returns HTTP 200, but doc is not saved in couchdb.
Again trying the same request,
HTTP Put - Returns HTTP 200 and adds the doc in database.
HTTP PUT request needs to be sent twice to create and save the doc.
I have checked that the above bug is reproducible for deleted docs, i.e the response for GET _id is {"error":"not_found","reason":"deleted"}.
This looks like a bug in CouchDB to me, could you please let us know if you could think of any scenario where above error might occur and any possible workarounds/solutions ?

Couchdb has a builtin mechanism to ensure that you do not overwrite the same document as someone else.
If you PUT any existing document, you'll have to accompany this process with the current doc._rev value, so that couchdb can confirm the document you are updating is based on the most recent version in the database.
I've not come across this case with deletions, but it makes sense to me that couchdb should not allow you to overwrite a deleted document as the assumption should be, you just don't know about the deletion.
Have you tried if you can access the revision of the deleted document and if so, whether by adding it to the new document, you can succeed with the PUT on the first call?

Related

Syncing Problems with Xamarin Forms and Azure Easy Tables

I've been working on a Xamarin.Forms application in Visual Studio using Azure for the backend for a while now, and I've come across a really strange issue.
Please note, that I am following the methods mentioned in this blog
For some strange reason the PullAsync() method seems to have some bizarre problems. Any data that I create and sync will only be pulled by PullAsync() from that solution. What I mean by that is that if I create another solution that accesses the exact same backend, it can perform it's own create/sync data, but will not bring over the data generated by the other solution, even though they both seem to have the exact same access. This appears to be some kind of a security feature/issue, but I can't quite make sense of it.
Has anyone else encountered this at all? Was there a work-around at all? This could potentially cause problems down the road if I were to ever want to create another solution that accesses the same system/data for whatever reason.
For some strange reason the PullAsync() method seems to have some bizarre problems. Any data that I create and sync will only be pulled by PullAsync() from that solution.
According to your provided tutorial, I found that the related PullAsync is using Incremental Sync.
await coffeeTable.PullAsync("allCoffees", coffeeTable.CreateQuery());
Incremental Sync:
the first parameter to the pull operation is a query name that is used only on the client. If you use a non-null query name, the Azure Mobile SDK performs an incremental sync. Each time a pull operation returns a set of results, the latest updatedAt timestamp from that result set is stored in the SDK local system tables. Subsequent pull operations retrieve only records after that timestamp.
Here is my test, you could refer to it for a better understanding of Incremental Sync:
Client : await todoTable.PullAsync("todoItems-02", todoTable.CreateQuery());
The client SDK would check if there has a record with the id equals deltaToken|{table-name}|{query-id} from the __config table of your SQLite local store.
If there has no record, then the SDK would send a request as following for pulling your records:
https://{your-mobileapp-name}.azurewebsites.net/tables/TodoItem?$filter=(updatedAt%20ge%20datetimeoffset'1970-01-01T00%3A00%3A00.0000000%2B00%3A00')&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
Note: the $filter would be set as (updatedAt ge datetimeoffset'1970-01-01T00:00:00.0000000+00:00')
While there has a record, then the SDK would pick up the value as the latest updatedAt timestamp and send the request as follows:
https://{your-mobileapp-name}.azurewebsites.net/tables/TodoItem?$filter=(updatedAt%20ge%20datetimeoffset'2017-06-26T02%3A44%3A25.3940000%2B00%3A00')&$orderby=updatedAt&$skip=0&$top=50&__includeDeleted=true
Per my understanding, if you handle the same logical query with the same query id (non-null) in different mobile client, you need to make sure the local db is newly created by each client. Also, if you want to opt out of incremental sync, pass null as the query ID. In this case, all records are retrieved on every call to PullAsync, which is potentially inefficient. For more details, you could refer to How offline synchronization works.
Additionally, you could leverage fiddler for capturing the network traces when you invoke the PullAsync, in order to troubleshoot your issue.

CouchDB - Get DB's update_seq based on document

I want to get all documents inside a CouchDB database and then listen to changes on that database. I could:
1- Get the docs using the _all_docs view. /db/_all_docs
2- Get the current db update_seq. /db .
3- listen to the changes in the database. /db/_changes?since=update_seq
But what if one or more documents are created right after I query the _all_docs view and before I get the update_seq? If that happens when I listen to the changes which happened after the update_seq I'll never receive those documents.
Is there a way to know what was the DB's update_seq when a given document had a given revision? With that, I could be 100% sure I'll never miss a document.
Add update_seq=true to your request for _all_docs, you'll get the update_seq for the database at that time. (this avoids the race condition you are afraid of)

GETting a document within a Document Update Handler

Is it possible to query (GET) a document from within a document update handler in CouchDB?
I have written a simple document update handler in CouchDB 2.0 to accept a POST from a third party (CognitoForms). This works fine, and I take the ID from their JSON payload and use that as the doc _id.
You can then specify an 'update' URI in CognitoForms, so I could create a new update handler or use the same one. However, in CognitoForms:
The update does a POST rather than a PUT
There does not appear to be a way to send any query parameters
As the ID for the document which needs to be updated is within the body, I could use this to query the database for the document, get the _rev, and return the payload with the _id and _rev to perform the update. However, I simply don't know if I can do such a query within the update handler. I feel like I am either missing something obvious, or there is a very good reason that I wouldn't be allowed to do that.
Thanks very much
edit: I should add that I understand I could create a small application to parse the request before forwarding on to couchdb, but I was interested to see if I could implement this in couchdb only to understand how far I can get without another layer!
In your particular case, it's quite hard to do this. A document update handler is basically a pure function that gets the data it needs and returns a response, but it has no way to reach out into the database.
If you add a doc id to the url, the update function gets the doc from the database as a parameter. For details see the CouchDB docs for update functions.
The way to a possible solution is to use a rewrite in CouchDB in order to extract the id from the body. In CouchDB 2.0, a new way for rewrites as functions has been introduced.
For pushing the limits, using a rewrite function for this sounds like fun. But for a production use case, it's probably easier and more maintainable to create a small node.js app that parses the body.

How can I intercept a call from PouchDB to CouchDB, using .net

I am learning PouchDB with CouchDB and trying to wrap my head around intercepting documents to the couchdb server and performing an action on it wether it be creating other documents, updating the user table, etc.
On the server the json document will be treated through a business layer before it is submitted to the couchdb server, preferably in .net.
Is this possible? If not, is there a way to do so?
Thanks!
On the server side, you can listen to the _changes feed from CouchDB (docs here) and react whenever a document is added, modified, or deleted. This could be useful for reporting/messaging/aggregation/etc.
Alternatively, if you want to do some schema validation on the documents before they are accepted, then you should look into adding a design doc with a validate_doc_update field (docs here).

Query changes in specific document ids in CouchDb

I have a mobile app that stores data (fetched from a remote CouchDb instance) to a local SQLite database. Sometimes a sync request occurs, and I would like to know of all items in the local database whether their counterparts have changed on the server. (So, whether their revision is newer than the one in the local database.)
But how can I request only the specific items in the local database, without making hundreds of separate requests, and without fetching all the documents in the huge remote database?
The way I currently do it, is: for each local document, first get the HTTP header, and download the body only if the header shows a newer revision than the local doc has. I worry that for users that store a lot of items locally, this will result in a lot of HTTP request
What about using the Change Notification API?
Your app could request all recent changes, and then check if any of the local files has changed on the server.
Adding a filter might help getting only interesting changes.

Resources