Possible to replicate couch database with illegal name - couchdb

I'm using this command to replicate a 100mb database
curl -H 'Content-Type: application/json' \
-X POST http://localhost:5984/_replicate \
-d '{"source": "http://example.com:5984/bad_name_with_underscore", "target": "good_name"}'
I cannot replicate, because CouchDB says the source database name contains illegal chars. I can understand CouchDB folks discourage user to create bad database name, but reading from it is no harm.
I'm not an admin of source CouchDB, so I tried to export database as JSON and then bulk put to new database. But I met {"error":"bad_request","reason":"Missing JSON list of 'docs'"}. Although I have tried to modify the dump.json by changing the structure to {"docs": [...]}.
I'd like to know, is there any other way I can replicate this database with some underscore in name?

I have resolved the problem by using a client - PouchDB. Here is the code.
const PouchDB = require('pouchdb')
const source = new PouchDB("http://example.com:5984/bad_name_with_underscore")
source.replicate.to("http://localhost:5984/good_name")
.on('complete', console.log)
.on('error', console.error)
This works pretty well, so I post this to share with you all.

Related

swagger-js: how to add authorization headers?

I'm trying to do something very simple: add api key authorization header in a post request.
What I tried so far:
add it under headers key in requestOptions
add it when creating the client under authorization key
this is where the search space begins to expand: which key do I add? the security type apiKey? Whatever key I gave it in my spec? The actual header name? (none of those worked, btw)
Unfortunately, I could not find any helpful info in documentation (actually I could not find any documentation other than the README and the FAQ pages which do not provide disambiguation in this matter).
So, any practical example and/or point to un/official docs that show how to work with this thing would be greatly appreciated.
So, from digging around in swagger-js code, "Whatever key I gave it in my spec" is the way to go. Meaning, if your security schemes look like this:
components:
securitySchemes:
ymlSpecAuthKeyName: # <-- also swagger-js key
type: apiKey
name: X-Auth-Header-Name
in: header
and you want your request to look like this:
curl -X POST "http://your-api-url.com/doc-you-want-to-create" \
-H "X-Auth-Header-Name: api-key-header-value" \
-H "Content-Type: application/json" \
-d "{\"json-request-body\": \"goes-here\"}"
Then you should make a swagger-js client like this:
let client = await Swagger({
spec: spec,
authorizations: {
ymlSpecAuthKeyName: 'api-key-header-value',
}
});

Get couchdb views to process design-docs as well as other docs

I am trying to get a view in couchdb to include design docs. I have done it in the past, but can not get it to work today.
In a past couchapp there is a file called options.json that contains the text:
{
"include_design": "true"
}
This results in the design doc containing
"options": {
"include_design": "true"
},
I added this to the new project, but still the design doc is not processed by my views. Is there something that I missed?
CouchDB 1.7.1
According to this documentation, include_design option is a boolean.
I double-checked CouchDB to see how it saves Boolean values by adding a document to a sample database with a Boolean value for one of the keys:
$ cat doc--0000
{"time":"2011", "address":"CT", "include":true}
$ curl -k -X PUT https://admin:**#192.168.1.106:6984/sample/doc--0000 -d #doc--0000
{"ok":true,"id":"doc--0000","rev":"1-e269c17275e2d21ba9100cd65b304d70"}
$ curl -k -X GET https://admin:**#192.168.1.106:6984/sample/doc--0000
{"_id":"doc--0000","_rev":"1-e269c17275e2d21ba9100cd65b304d70","time":"2011","address":"CT","include":true}
The double-check confirms that the Boolean values are saved as true NOT "true". I'm not sure, maybe that's the cause of the issue.
#user3405291 is correct the problem is with the string "true" instead of boolean true. CouchDB doesn't save this. Your view is run on the server as a javascript script so you should write it like you write javascript anywhere.

How to purge CouchDB documents

I need to fully delete, as in Purge, several documents from CouchDB version 2.1.
I have been reading about /db/_purge on docs.couchdb.org, but the process is not clear to me. There is a sentence "The format of the request must include the document ID and one or more revisions that must be purged".
How do I do this in Postman or in a browser? Do I actually enclose my doc _id & rev(s) in braces? I am struggling with how to correctly format a _purge request.
As of now, it is my understanding that _purge does not work in 2.0 and 2.1.
For more information look at this JIRA post.
Note that document purging is only supported in CouchDB versions prior to 2.0, and from 2.3 onward. Early versions of clustered CouchDB (2.0.x and 2.1.x) did not support purging, although this was poorly documented!
The documentation explains, and provides an example:
{
"c6114c65e295552ab1019e2b046b10e": [
"3-b06fcd1c1c9e0ec7c480ee8aa467bf3b",
"3-0e871ef78849b0c206091f1a7af6ec41"
]
}
So that means in the format of:
{
"<doc id>": [
"<rev>",
"<rev>"
]
}
This should be the body of your HTTP request, with a Content-Type of application/json. You won't be able to do that in a browser, without using JavaScript.
With curl it would look like:
curl -X POST http://<server url>/<database>/_purge -H 'Content-Type: application/json' -d '{"<doc id>":["<rev1>","<rev2>"]}'
I just wrote this tool to purge and compact databases in CouchDB.
https://github.com/nisbus/couch_db_cleaner
I hope the documentation in the README is clear and it helps.

Watson Concept-Insights document list/limit option not working in nodeJS

I am building a new corpus using Watson Concept-Insights. I've created about 100 documents so far using nodeJS. If I use curl to list the documents, I can find all of them. However when I nodeJS to list the same set of documents, it consistently ignores the limit value and returns the default of 20 documents. Help!!
Essential code follows (account key replaced with 'myAccount'):
var watson = require('watson-developer-cloud');
var concept_insights = watson.concept_insights({ yada yada... this all works }
params = { 'corpus': '/corpora/myAccount/theAdviser', 'limit': 200 };
concept_insights.corpora.listDocuments(params, function(err,_res) {
if (err) { console.log(err); }
else { console.log(JSON.stringify(_res, null, 2));
res.send(JSON.stringify(_res, null, 2)); }
});
No matter what value is entered for the limit option, I always get 20 results. CURL, on the other hand, returns the full list or a subset based on the specified limit.
The equivalent working curl statement is:
curl -u "{userID}":"{password}" "https://gateway.watsonplatform.net/concept-insights-beta/api/v2/corpora/myAccount/theAdviser/documents?limit=200"
It looks like this was an oversight in the npm module. I just added support for the limit param, it should be released as v1.9.1 once the CI loop finishes.
Unfortunately, this does not seem to be reproducible for the corpora I have access to. For example, this curl:
curl -s -u username:password \
"https://gateway.watsonplatform.net/concept-insights/api/v2/corpora/public/TEDTalks/documents?limit=100"
Produces a list of 100 documents for me. If you have jq installed you can verify:
curl -s -u username:password \
"https://gateway.watsonplatform.net/concept-insights/api/v2/corpora/public/TEDTalks/documents?limit=100" \
| jq '.[] | length'
100
Another way to try to look at your corpus, is checking the "Concept Insights Dashboard" available in Bluemix by clicking on your service instance tile (the icon that is currently in use by your application). The first page of the dashboard allows you to select the corpus, and it reports a high-level summary of the corpus (including number of documents).

How can you simulate a conflict in CouchDB without using replication?

I'd like to write a unit test for my app that simulates a conflict during replication. Is there a way to simulate a conflict using only a single CouchDB database and server?
I assume you want to get a document containing a conflict in your database, rather than a 409 Conflict response?
So, create a document in the database with a known _id:
$ curl http://localhost:5984/scratch/foo -X PUT -H "Content-Type: application/json" -d '{}'
{"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
Then use the bulk docs API with the all_or_nothing: true option to update the same document with a deliberately bad or no _rev, adding some different document attributes for good measure:
$ curl http://localhost:5984/scratch/_bulk_docs -X POST -H "Content-Type: application/json" -d '{"all_or_nothing": true, "docs": [{"_id": "foo", "abc": 123}]}'
[{"id":"foo","rev":"1-15c813a2b4b312c6915821b01a1986c5"}]
You should then have a conflict in the document:
$ curl http://localhost:5984/scratch/foo?conflicts=true
{"_id":"foo","_rev":"1-967a00dff5e02add41819138abb3284d","_conflicts":["1-15c813a2b4b312c6915821b01a1986c5"]}
You can also perform a normal query with ?new_edits=false as described by CouchDB committer Randall Leeds.
$ curl http://localhost:5984/scratch?new_edits=false -X POST -H "Content-Type: application/json" -d '{"_id": "foo", "abc": 123}'
Googled further after asking the question, and it looks like the answer is to use the all-or-nothing mode of the bulk document API.
http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API
Look near the end of the page.
Just post two documents with the same _id attribute. This creates a conflict since the 2nd doc will not contain the proper _rev attribute. Remember, you need to include the latest _rev attribute in each subsequent post so that CouchDB knows you are up to date.
Also, you can create two databases on the same server and replicate between those.

Resources