1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#!/usr/bin/ruby
#
# This script will update the values of a particular couchdb document. The benefit of this little script over
# using a simple curl command for updating a document is this:
#
# * exit non-zero status if document was not updated.
# * updates existing documents easily, taking care of the _rev id for you.
# * if document doesn't exist, it is created
#
# REQUIREMENTS
#
# gem 'couchrest'
#
# USAGE
#
# couch-doc-update --host <host> --db <db> --id <doc_id> --data <json>
#
# EXAMPLE
#
# create a new user:
# couch-doc-update --db _users --id org.couchdb.user:ca_daemon --data '{"type": "user", "name": "ca_daemon", "roles": ["certs"], "password": "sshhhh"}'
#
# update a user:
# couch-doc-update --db _users --id org.couchdb.user:ca_daemon --data '{"password":"sssshhh"}'
#
# To update the _users DB on bigcouch, you must connect to port 5986 instead of the default couchdb port 5984
#
begin; require 'rubygems'; rescue LoadError; end # optionally load rubygems
require 'couchrest'
require 'json'
def main
db, id, data = process_options
result = set_document(db, id, data)
exit 0 if result['ok']
raise StandardError.new(result.inspect)
rescue StandardError => exc
puts "ERROR: " + exc.to_s
exit 1
end
def process_options
#
# parse options
#
host = nil
db_name = nil
doc_id = nil
new_data = nil
loop do
case ARGV[0]
when '--host' then ARGV.shift; host = ARGV.shift
when '--db' then ARGV.shift; db_name = ARGV.shift
when '--id' then ARGV.shift; doc_id = ARGV.shift
when '--data' then ARGV.shift; new_data = ARGV.shift
when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
else break
end
end
usage("Missing required option") unless db_name && doc_id && new_data
new_data = JSON.parse(new_data)
db = CouchRest.database(connection_string(db_name, host))
return db, doc_id, new_data
end
#
# update document
#
def set_document(db, id, data)
doc = get_document(db, id)
if doc
doc.id ||= id
update_document(db, doc, data)
else
create_document(db, id, data)
end
end
def get_document(db, doc_id)
begin
db.get(doc_id)
rescue RestClient::ResourceNotFound
nil
end
end
def update_document(db, doc, data)
doc.reject! {|k,v| !k.start_with? '_'}
doc.merge! data
db.save_doc(doc)
end
def create_document(db, doc_id, data)
data["_id"] = doc_id
db.save_doc(data)
end
def connection_string(database, host)
protocol = "http"
#hostname = "127.0.0.1"
port = "5984"
username = "admin"
password = ""
netrc = File.read('/etc/couchdb/couchdb.netrc')
netrc.scan(/\w+ [\w\.]+/).each do |key_value|
key, value = key_value.split ' '
case key
when "machine" then host ||= value + ':' + port
when "login" then username = value
when "password" then password = value
end
end
host ||= '127.0.0.1:5984'
"%s://%s:%s@%s/%s" % [protocol, username, password, host, database]
end
def usage(s)
$stderr.puts(s)
$stderr.puts("Usage: #{File.basename($0)} --host <host> --db <db> --id <doc_id> --data <json>")
exit(2)
end
main()
|