couchup 0.0.13 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/Rakefile +8 -0
- data/Readme.markdown +55 -11
- data/TODO +14 -1
- data/bin/couchup +24 -3
- data/lib/couchup.rb +10 -6
- data/lib/couchup/command_extensions.rb +15 -0
- data/lib/couchup/commands/compact.rb +18 -2
- data/lib/couchup/commands/connect.rb +8 -2
- data/lib/couchup/commands/create.rb +37 -22
- data/lib/couchup/commands/drop.rb +7 -3
- data/lib/couchup/commands/get.rb +8 -1
- data/lib/couchup/commands/help.rb +18 -4
- data/lib/couchup/commands/map.rb +7 -1
- data/lib/couchup/commands/rename.rb +22 -0
- data/lib/couchup/commands/replicate_to.rb +8 -2
- data/lib/couchup/commands/restart.rb +5 -1
- data/lib/couchup/commands/show.rb +7 -1
- data/lib/couchup/commands/use.rb +8 -2
- data/lib/couchup/commands/view.rb +7 -1
- data/lib/couchup/couchup.rb +20 -4
- data/lib/couchup/extensions/symbol.rb +4 -0
- data/lib/couchup/mapreduce.rb +2 -2
- data/lib/couchup/short_hands.rb +40 -0
- data/lib/couchup/version.rb +1 -1
- data/lib/couchup/view.rb +6 -3
- data/spec/commands/compact_spec.rb +35 -0
- data/spec/commands/map_spec.rb +114 -0
- data/spec/commands/use_spec.rb +15 -0
- data/spec/couchup_spec.rb +0 -0
- data/spec/spec_helper.rb +45 -0
- data/spec/specs.opts +5 -0
- metadata +19 -5
data/Gemfile
CHANGED
data/Rakefile
CHANGED
data/Readme.markdown
CHANGED
@@ -4,7 +4,7 @@ Couchup
|
|
4
4
|
This is a command line interface to CouchDb.
|
5
5
|
|
6
6
|
|
7
|
-
|
7
|
+
Installation
|
8
8
|
===========
|
9
9
|
|
10
10
|
gem install couchup
|
@@ -15,6 +15,7 @@ Usage
|
|
15
15
|
======
|
16
16
|
|
17
17
|
Couchup is a command line utility piggybacking on the irb. So you can do all the ruby stuff in it.
|
18
|
+
|
18
19
|
Type help on command line to list the stuff you can do with couchup.
|
19
20
|
|
20
21
|
|
@@ -23,11 +24,12 @@ $ couchup
|
|
23
24
|
|
24
25
|
|
25
26
|
You see a bunch of commands that you can use.
|
27
|
+
|
26
28
|
Remember this is just an IRB, so the command syntax is a little verbose.
|
27
29
|
|
28
30
|
create :database, :riders (Note the commas and symbols)
|
29
31
|
|
30
|
-
Also symbols and strings can be used
|
32
|
+
Also symbols and strings can be used interchangeably, So the above is the same as
|
31
33
|
|
32
34
|
create "database", "riders"
|
33
35
|
|
@@ -40,9 +42,16 @@ Command line Params
|
|
40
42
|
> couchup --help will print the help
|
41
43
|
|
42
44
|
use -h (or--host) to set the host machine to connect to
|
45
|
+
|
43
46
|
use -p (or --port) to set the port of the host couchdb
|
47
|
+
|
44
48
|
use -d (or --database) to set the database to use by default
|
45
49
|
|
50
|
+
use -u (or --username) to use a specific user login (when in admin mode)
|
51
|
+
|
52
|
+
use -a (or --password) to specify the password (when in admin mode)
|
53
|
+
|
54
|
+
|
46
55
|
|
47
56
|
Basics
|
48
57
|
--------
|
@@ -66,7 +75,11 @@ Most Couchup commands need you to be on a specific database.
|
|
66
75
|
Shortcuts
|
67
76
|
----------
|
68
77
|
|
69
|
-
last_result or __ are short hands
|
78
|
+
*last_result* or *__* are short hands for the last result returned by couch operations( Note this is not the same as _ that is available in irb).
|
79
|
+
|
80
|
+
These are typically json documents( or array of documents)
|
81
|
+
|
82
|
+
|
70
83
|
Most commands that are in the form of <operation> <:view|| :database || :doc> have short hands like <operation>_<view> or <operation>_database
|
71
84
|
|
72
85
|
eg. *create_database :foo* is same as *create :database, :foo*
|
@@ -91,8 +104,11 @@ gets docucment by the given ID.
|
|
91
104
|
--------------
|
92
105
|
|
93
106
|
There are 2 different commands.
|
107
|
+
|
94
108
|
map Will just run the map function
|
109
|
+
|
95
110
|
view : will run both the map and reduce.
|
111
|
+
|
96
112
|
They have very similar semantics, except for where noted.
|
97
113
|
|
98
114
|
> map "Rider/all"
|
@@ -108,16 +124,16 @@ will return only only the document matching the above key.
|
|
108
124
|
|
109
125
|
The following will query the view with a post to get all the matching keys.
|
110
126
|
|
111
|
-
map "Rider/all", ["78ea2a07be87b6fa0e4afed5d81f3729", "ee23399aad3f8685e64f455504000d49"]
|
127
|
+
> map "Rider/all", ["78ea2a07be87b6fa0e4afed5d81f3729", "ee23399aad3f8685e64f455504000d49"]
|
112
128
|
|
113
129
|
The following will query the view with a startkey and endkey semantics.
|
114
130
|
|
115
|
-
map "Rider/all", :startkey=> "78ea2a07be87b6fa0e4afed5d81f3729", :endkey=> "ee23399aad3f8685e64f455504000d49"
|
131
|
+
> map "Rider/all", :startkey=> "78ea2a07be87b6fa0e4afed5d81f3729", :endkey=> "ee23399aad3f8685e64f455504000d49"
|
116
132
|
|
117
133
|
|
118
134
|
The same rules apply for *view* command as well, and additionally it takes the group_level parameter as well.
|
119
135
|
|
120
|
-
view "Rider/all", :startkey=> "78ea2a07be87b6fa0e4afed5d81f3729", :endkey=> "ee23399aad3f8685e64f455504000d49"
|
136
|
+
> view "Rider/all", :startkey=> "78ea2a07be87b6fa0e4afed5d81f3729", :endkey=> "ee23399aad3f8685e64f455504000d49"
|
121
137
|
|
122
138
|
|
123
139
|
# Creating and modifying views.
|
@@ -129,22 +145,50 @@ It is important to set the EDITOR variable before running couchup, because we us
|
|
129
145
|
|
130
146
|
Will pop a textmate/emacs/vi window with some templates. If the view exists it will show the existing code. So you can modify it.
|
131
147
|
|
132
|
-
|
133
148
|
To cancel creation of the view, just empty the contents of the file and save.
|
134
149
|
|
150
|
+
If you want to specify the map and view function on couchup
|
151
|
+
|
152
|
+
> create :view, 'Rider/test', "function(doc) { if( doc.name) emit(doc.name, 1);}"
|
153
|
+
|
154
|
+
|
135
155
|
# Modifying Documents
|
136
156
|
-----------------------
|
137
157
|
|
138
|
-
We use the last_result that is described in the Basics section, and leverage ruby to
|
158
|
+
We use the last_result that is described in the Basics section, and leverage ruby to change documents in couchdb
|
139
159
|
|
140
|
-
get("<id>")
|
141
|
-
last_result[:number] = 100
|
142
|
-
last_result.save
|
160
|
+
> get("<id>")
|
161
|
+
> last_result[:number] = 100
|
162
|
+
> last_result.save
|
143
163
|
|
144
164
|
|
145
165
|
You could do this with the view results as well.
|
146
166
|
|
147
167
|
|
168
|
+
# Non Interactive Mode
|
169
|
+
------------------------
|
170
|
+
|
171
|
+
You can just run a few commands on couch by using the -c (--command) option for couchup
|
172
|
+
|
173
|
+
e.g :
|
174
|
+
> couchup -d riders -c map Riders/by_arrival_time
|
175
|
+
|
176
|
+
Will run the Riders/by_arrival_time map function on riders database.
|
177
|
+
|
178
|
+
|
179
|
+
Note the absence of symbols and strings in such a mode
|
180
|
+
|
181
|
+
Multi line commands are supported by use of ';'
|
182
|
+
|
183
|
+
e.g:
|
184
|
+
|
185
|
+
> couchup -c create database new_riders; use riders; replicate_to new_riders
|
186
|
+
|
187
|
+
|
188
|
+
|
189
|
+
|
190
|
+
|
191
|
+
|
148
192
|
|
149
193
|
|
150
194
|
|
data/TODO
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
-
Pretty print
|
2
1
|
Paging
|
2
|
+
Temp view.
|
3
|
+
Validation of inputs.
|
3
4
|
Decent Editor -> https://github.com/jberkel/interactive_editor
|
5
|
+
Scripting, piping to couchup.
|
4
6
|
Conflicts
|
5
7
|
Attachments
|
8
|
+
Try and save views. Save to temp view, show results to the users and then save to real
|
9
|
+
Username password based access
|
10
|
+
|
11
|
+
Debugging information on debug
|
12
|
+
|
13
|
+
Bigcouch
|
14
|
+
Nodes Management.
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
Lucene
|
data/bin/couchup
CHANGED
@@ -13,7 +13,6 @@ if File.exists?( File.expand_path(rcfile = "~/.couchuprc") )
|
|
13
13
|
load(rcfile)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
16
|
options = {}
|
18
17
|
OptionParser.new do |opts|
|
19
18
|
opts.banner = "Usage: example.rb [options]"
|
@@ -30,17 +29,39 @@ OptionParser.new do |opts|
|
|
30
29
|
options[:db] = db
|
31
30
|
end
|
32
31
|
|
32
|
+
opts.on("-u", "--username USER", "Database to connect to.") do |user|
|
33
|
+
options[:user] = user
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("-a", "--password PASSWORD", "Database to connect to.") do |password|
|
37
|
+
options[:password] = password
|
38
|
+
end
|
39
|
+
|
33
40
|
opts.on("-b", "--debug", "Show debugging information") do |bug|
|
34
41
|
options[:bug] = bug
|
35
42
|
end
|
43
|
+
|
44
|
+
opts.on("-c", "--command COMMAND", "Runs a specific command and prints the result, seperate with ';' to run multiple commands") do |c|
|
45
|
+
options[:command] = c
|
46
|
+
end
|
36
47
|
|
37
48
|
end.parse!
|
38
49
|
|
39
50
|
host = options[:host] || 'localhost'
|
40
51
|
port = options[:port] || "5984"
|
41
|
-
Couchup::Commands::Connect.new.run(host, port)
|
52
|
+
Couchup::Commands::Connect.new.run(host, port, options[:user], options[:password])
|
42
53
|
Couchup::Commands::Use.new.run(options[:db]) unless options[:db].nil?
|
43
|
-
Couchup.debug = true if options[:bug]
|
54
|
+
Couchup::Couchup.debug = true if options[:bug]
|
55
|
+
|
56
|
+
unless(options[:command].nil?)
|
57
|
+
commands = options[:command].split( ";")
|
58
|
+
commands.each do |command|
|
59
|
+
c, params = command.split
|
60
|
+
ap send(c, *params)
|
61
|
+
end
|
62
|
+
exit
|
63
|
+
end
|
64
|
+
|
44
65
|
ap "Type help to view the list of things you can do. And Yeah Relax."
|
45
66
|
|
46
67
|
ARGV.clear
|
data/lib/couchup.rb
CHANGED
@@ -8,26 +8,30 @@ rescue LoadError
|
|
8
8
|
end
|
9
9
|
|
10
10
|
require File.expand_path '../couchup/couchup', __FILE__
|
11
|
+
Dir[File.expand_path('../couchup/*.rb',__FILE__)].each { |file| require file}
|
12
|
+
|
11
13
|
Dir[File.expand_path('../couchup/commands/*.rb',__FILE__)].each { |file| require file}
|
12
14
|
Dir[File.expand_path('../couchup/extensions/*.rb',__FILE__)].each { |file| require file}
|
13
|
-
Dir[File.expand_path('../couchup/*.rb',__FILE__)].each { |file| require file}
|
14
15
|
|
16
|
+
include Couchup::ShortHands
|
15
17
|
|
16
18
|
Couchup::Commands.constants.each do |c|
|
17
19
|
instance_eval "
|
18
|
-
def last_result
|
19
|
-
Couchup::Couchup.last_result
|
20
|
-
end
|
21
|
-
alias __ last_result
|
22
20
|
def #{c.underscore}(*args)
|
23
21
|
begin
|
24
22
|
instance = Couchup::Commands.const_get(:#{c}).new
|
25
23
|
Couchup::Couchup.last_result = instance.run(*args)
|
26
24
|
nil
|
25
|
+
rescue ArgumentError => e
|
26
|
+
ap e
|
27
27
|
rescue
|
28
|
-
puts $!.class
|
29
28
|
ap $!.inspect
|
30
29
|
ap $!.backtrace if Couchup::Couchup.debug?
|
31
30
|
end
|
32
31
|
end"
|
33
32
|
end
|
33
|
+
instance_eval "def last_result
|
34
|
+
Couchup::Couchup.last_result
|
35
|
+
end
|
36
|
+
alias __ last_result
|
37
|
+
"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Couchup
|
2
|
+
module CommandExtensions
|
3
|
+
module ClassMethods
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.included(receiver)
|
7
|
+
receiver.extend ClassMethods
|
8
|
+
end
|
9
|
+
|
10
|
+
def needs_db!
|
11
|
+
raise ArgumentError, "Please select a database before executing this request" if ::Couchup::Couchup.database.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -1,11 +1,27 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Compact
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
5
|
-
|
6
|
+
db = params.shift
|
7
|
+
if(db.nil?)
|
8
|
+
needs_db!
|
9
|
+
instance = Couchup.database
|
10
|
+
else
|
11
|
+
instance = Couchup.new_database(db)
|
12
|
+
end
|
13
|
+
if instance.nil?
|
14
|
+
ap "Database not found."
|
15
|
+
else
|
16
|
+
instance.compact!
|
17
|
+
end
|
18
|
+
|
6
19
|
end
|
7
20
|
def self.describe
|
8
|
-
"Compacts the database. To preserve space"
|
21
|
+
{:description => "Compacts the current database or specified database. To preserve space.",
|
22
|
+
:usage => "compact [db_name]",
|
23
|
+
:examples =>[ "compact", "compact 'Riders/winners"]
|
24
|
+
}
|
9
25
|
end
|
10
26
|
end
|
11
27
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Connect
|
4
|
-
def run(host = 'localhost', port = 5984)
|
4
|
+
def run(host = 'localhost', port = 5984, user = nil, pass = nil)
|
5
5
|
Couchup.host = host
|
6
6
|
Couchup.port = port
|
7
|
+
Couchup.user = user
|
8
|
+
Couchup.password = pass
|
7
9
|
if(Couchup.ready?)
|
8
10
|
ap "Connected to #{Couchup.host}:#{Couchup.port}"
|
9
11
|
else
|
@@ -11,7 +13,11 @@ module Couchup
|
|
11
13
|
end
|
12
14
|
end
|
13
15
|
def self.describe
|
14
|
-
|
16
|
+
{
|
17
|
+
:description => "Connects to the couch server. Takes host and port defaults to 5984",
|
18
|
+
:usage => 'connect [database], [port]',
|
19
|
+
:examples => ["connect", "connect bigcouch.test.com", "connect 'bigcouch.test.com', 5986"]
|
20
|
+
}
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
@@ -1,41 +1,56 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Create
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
5
6
|
what = params.shift.to_s
|
6
7
|
if(what == 'view')
|
7
|
-
|
8
|
+
needs_db!
|
9
|
+
create_view(params.shift, *params)
|
8
10
|
else
|
9
|
-
|
10
|
-
|
11
|
+
new_db = params.shift.to_s
|
12
|
+
Couchup.server.database!(new_db)
|
13
|
+
Use.new.run(new_db)
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
|
-
def create_view(name)
|
17
|
+
def create_view(name, *params)
|
15
18
|
raise "Please set your EDITOR env variable before using view" if ENV['EDITOR'].nil?
|
16
|
-
view = ::Couchup::View.new(name)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
view = ::Couchup::View.new(name)
|
20
|
+
if(params.size == 0)
|
21
|
+
file = Tempfile.new(name.gsub("/", "_"))
|
22
|
+
tmp_file_path = file.path
|
23
|
+
file.write("------BEGIN Map-------\n")
|
24
|
+
file.write( view.map? ? view.map : ::Couchup::View::MAP_TEMPLATE)
|
25
|
+
file.write("\n------END------\n")
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
file.write("\n------BEGIN Reduce(Remove the function if you don't want a reduce)-------\n")
|
28
|
+
file.write(view.reduce? ? view.reduce: ::Couchup::View::REDUCE_TEMPLATE )
|
29
|
+
file.write("\n------END------\n")
|
30
|
+
file.write("\nDelete Everything to do nothing.\n")
|
31
|
+
file.close
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
`#{ENV['EDITOR']} #{tmp_file_path}`
|
34
|
+
contents = File.open(tmp_file_path).read
|
35
|
+
unless contents.blank?
|
36
|
+
::Couchup::View.create_from_file(name, contents)
|
37
|
+
end
|
38
|
+
file.close
|
39
|
+
file.unlink
|
40
|
+
else
|
41
|
+
map = params.shift
|
42
|
+
reduce = params.shift
|
43
|
+
::Couchup::View.create(name, map, reduce)
|
44
|
+
end
|
34
45
|
end
|
35
46
|
|
36
47
|
def self.describe
|
37
|
-
|
48
|
+
{
|
49
|
+
:description => "Creates a new database and switches to the database",
|
50
|
+
:usage => " create :database | :view , name",
|
51
|
+
:examples => ["create :database, riders", "create :view, 'Riders/test'"]
|
52
|
+
}
|
38
53
|
end
|
39
54
|
end
|
40
55
|
end
|
41
|
-
end
|
56
|
+
end
|
@@ -1,17 +1,21 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Drop
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
5
6
|
op_type = params.shift.to_s
|
6
|
-
(params.first.nil? ? Couchup.database : Couchup.
|
7
|
+
(params.first.nil? ? Couchup.database : Couchup.new_database(params.first.to_s)).delete!
|
7
8
|
::Couchup::View.new(params.first).delete! if op_type == 'view'
|
8
9
|
Couchup.delete_doc(params.first) if op_type == 'doc'
|
9
10
|
Couchup.delete_all_docs(params.first) if op_type == 'all_docs'
|
10
|
-
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.describe
|
14
|
-
|
14
|
+
{
|
15
|
+
:description => "Drops specified object from couchdb",
|
16
|
+
:usage => "drop [:database | :view | :doc | :all_docs]",
|
17
|
+
:examples => ["drop :database, 'test'", "drop :view, 'Riders/top_ten'", "drop :doc, '23'", "drop :all_docs"]
|
18
|
+
}
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
data/lib/couchup/commands/get.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Get
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(id = nil)
|
6
|
+
needs_db!
|
5
7
|
match = id.nil? ? Couchup.all.collect{|c| c["doc"]} : Couchup.get(id)
|
6
8
|
ap match
|
7
9
|
match
|
8
10
|
end
|
9
11
|
|
10
12
|
def self.describe
|
11
|
-
|
13
|
+
{
|
14
|
+
:description => "Retrives documents from the current database",
|
15
|
+
:usage => "get [:doc], [<id>]",
|
16
|
+
:examples => ["get :doc, '2a663b5936f98fe225d64fcaa89e3281'", "get"]
|
17
|
+
}
|
18
|
+
|
12
19
|
end
|
13
20
|
end
|
14
21
|
end
|
@@ -2,17 +2,31 @@ module Couchup
|
|
2
2
|
module Commands
|
3
3
|
class Help
|
4
4
|
def run(param = nil)
|
5
|
-
|
6
|
-
|
5
|
+
param.nil? ? show_all : show(param.camelize)
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
def show(command)
|
9
|
+
k = Commands.const_get(command.to_s)
|
10
|
+
ap k.describe
|
11
|
+
end
|
12
|
+
|
13
|
+
def show_all
|
14
|
+
Commands.constants.each do |stuff|
|
7
15
|
k = Commands.const_get(stuff)
|
8
16
|
print stuff.underscore
|
9
17
|
print (stuff.underscore.size > 10) ? "\t" : "\t\t"
|
10
|
-
ap k.respond_to?(:describe) ? k.describe : "No Help"
|
18
|
+
ap k.respond_to?(:describe) ? k.describe[:description] : "No Help"
|
11
19
|
end
|
20
|
+
ap "Type help <command> for more detailed info"
|
12
21
|
end
|
13
22
|
|
14
23
|
def self.describe
|
15
|
-
|
24
|
+
{
|
25
|
+
:description => "Help on the system",
|
26
|
+
:usage => "help [<command>]",
|
27
|
+
:examples => ["help", "help :get"]
|
28
|
+
}
|
29
|
+
|
16
30
|
end
|
17
31
|
end
|
18
32
|
end
|
data/lib/couchup/commands/map.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Map
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
6
|
+
needs_db!
|
5
7
|
rows = MapReduce.map(*params)
|
6
8
|
ap "Found #{rows.size} item(s)"
|
7
9
|
ap rows
|
@@ -9,7 +11,11 @@ module Couchup
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def self.describe(p = nil)
|
12
|
-
|
14
|
+
{
|
15
|
+
:description => "Runs a view with just the map function and returns the results",
|
16
|
+
:usage => 'map <view_name> [options]',
|
17
|
+
:examples => ["map 'Rider/top_ten'","map 'Rider/top_ten', 10", "map 'Rider/top_ten', {:startkey => '10', :endkey => '20'}","map 'Rider/top_ten', [1,2,3,10]" ]
|
18
|
+
}
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Couchup
|
2
|
+
module Commands
|
3
|
+
class Rename
|
4
|
+
def run(*params)
|
5
|
+
ap "Move database means that we replicate to a new db and delete the current one. if there are lots of documents, view building will be slow."
|
6
|
+
src_db = CouchRest.database!("http://#{Couchup.host}:#{Couchup.port}/#{params.shift}")
|
7
|
+
dest_db = CouchRest.database!("http://#{Couchup.host}:#{Couchup.port}/#{params.shift}")
|
8
|
+
res = src_db.replicate_to(dest_db, false, true)
|
9
|
+
src_db.delete! if res["ok"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.describe
|
13
|
+
{
|
14
|
+
:description => "Renames database or a view both on the same Couch instance. Replicates to new db and deletes the old. Hence slow.",
|
15
|
+
:usage => "rename <src_database>, <target_database>",
|
16
|
+
:examples => ["rename 'riders_test', 'riders_development'"]
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class ReplicateTo
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
5
6
|
dest = params.shift
|
6
7
|
option = params.shift
|
7
|
-
|
8
|
+
needs_db!
|
9
|
+
dest_db = (dest =~ /(http\w:\/\/.*)\/(.*)/) ? CouchRest::Database.new(CouchRest::Server.new($1), $2) : CouchRest::Database.new(Couchup.server, dest)
|
8
10
|
Couchup.database.replicate_to dest_db, (option.to_s == "continous")
|
9
11
|
end
|
10
12
|
|
11
13
|
def self.describe
|
12
|
-
|
14
|
+
{
|
15
|
+
:description => "Allows replication to different databases",
|
16
|
+
:examples => ["replicate_to :riders_dev", "replicate_to 'http://foo.bar.com:5984/billing', :continous"],
|
17
|
+
:usage => "replicate_to <target_db>, options"
|
18
|
+
}
|
13
19
|
end
|
14
20
|
|
15
21
|
end
|
@@ -6,7 +6,11 @@ module Couchup
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.describe
|
9
|
-
|
9
|
+
{
|
10
|
+
:description => "Restarts the couchdb server. Please be careful with it. It will not prompt you for anything.",
|
11
|
+
:examples => ["restart"],
|
12
|
+
:usage => 'restart'
|
13
|
+
}
|
10
14
|
end
|
11
15
|
end
|
12
16
|
end
|
@@ -1,17 +1,23 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class Show
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*param)
|
5
6
|
option = param.first.to_s
|
6
7
|
if(option.blank? || option == 'databases' )
|
7
8
|
ap Couchup.databases
|
8
9
|
else
|
10
|
+
needs_db!
|
9
11
|
ap Couchup.views(param.second)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
13
15
|
def self.describe
|
14
|
-
|
16
|
+
{
|
17
|
+
:description => "show databases or views on the current instance/database",
|
18
|
+
:details => "show [:databases | :views], [:design]",
|
19
|
+
:examples => ["show", "show :databases", "show :views"]
|
20
|
+
}
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|
data/lib/couchup/commands/use.rb
CHANGED
@@ -5,14 +5,20 @@ module Couchup
|
|
5
5
|
db = database.to_s
|
6
6
|
if Couchup.databases.include? db
|
7
7
|
Couchup.database = db
|
8
|
-
|
8
|
+
info = Couchup.database.info
|
9
|
+
ap info
|
10
|
+
info
|
9
11
|
else
|
10
12
|
ap "Database was not found"
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
16
|
def self.describe
|
15
|
-
|
17
|
+
{
|
18
|
+
:description => "Use provided database",
|
19
|
+
:detail => "use <database>",
|
20
|
+
:examples => ["use 'riders'"]
|
21
|
+
}
|
16
22
|
end
|
17
23
|
end
|
18
24
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module Couchup
|
2
2
|
module Commands
|
3
3
|
class View
|
4
|
+
include ::Couchup::CommandExtensions
|
4
5
|
def run(*params)
|
6
|
+
needs_db!
|
5
7
|
rows = MapReduce.reduce(*params)
|
6
8
|
ap "Found #{rows.size} item(s)"
|
7
9
|
ap rows
|
@@ -9,7 +11,11 @@ module Couchup
|
|
9
11
|
end
|
10
12
|
|
11
13
|
def self.describe(params = nil)
|
12
|
-
|
14
|
+
{
|
15
|
+
:description => "Executes the given View. Runs Map and Reduce and retuns the results",
|
16
|
+
:usage => "view <view_name> [options]",
|
17
|
+
:examples => ["view 'Riders/top_ten'", "view 'Riders/top_ten', [10,100,200]", "view 'Riders/top_ten', 10", "view 'Riders/top_ten', {:group_level=>2, :group=> true}"]
|
18
|
+
}
|
13
19
|
end
|
14
20
|
end
|
15
21
|
end
|
data/lib/couchup/couchup.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
module Couchup
|
2
2
|
class Couchup
|
3
3
|
class << self
|
4
|
-
attr_accessor :port, :host
|
4
|
+
attr_accessor :port, :host, :user, :password
|
5
5
|
attr_accessor :last_result
|
6
|
+
|
6
7
|
def server
|
7
|
-
@server ||= CouchRest::Server.new(
|
8
|
+
@server ||= CouchRest::Server.new(host_string)
|
8
9
|
end
|
9
10
|
|
10
11
|
def database=(database)
|
11
|
-
@db = CouchRest.database!(
|
12
|
+
@db = database.nil? ? nil : CouchRest.database!(host_string(database))
|
12
13
|
end
|
13
|
-
|
14
|
+
|
15
|
+
|
16
|
+
def host_string(database=nil)
|
17
|
+
base_string = using_auth? ? "#{user}:#{password}@#{host}:#{port}" : "#{host}:#{port}"
|
18
|
+
database.blank? ? "http://#{base_string}" : "http://#{base_string}/#{database}"
|
19
|
+
end
|
20
|
+
def using_auth?
|
21
|
+
!user.blank?
|
22
|
+
end
|
23
|
+
|
24
|
+
def new_database(db)
|
25
|
+
CouchRest.database!(host_string(db))
|
26
|
+
end
|
27
|
+
|
14
28
|
def database
|
15
29
|
@db
|
16
30
|
end
|
17
31
|
|
32
|
+
|
18
33
|
def views(design = nil)
|
19
34
|
params = design.nil? ? {:startkey => '_design', :endkey => '_design0'} : {:key => "_design\\#{design}"}
|
20
35
|
designs = database.documents(params.merge(:include_docs => true))["rows"]
|
@@ -31,6 +46,7 @@ module Couchup
|
|
31
46
|
doc = database.get(id)
|
32
47
|
database.delete_doc(doc)
|
33
48
|
end
|
49
|
+
|
34
50
|
def delete_all_docs(view_name)
|
35
51
|
all_docs = view_name.nil? ? all : MapReduce.map(view_name)
|
36
52
|
all_docs.collect{|d| d["doc"]}.each do |doc|
|
data/lib/couchup/mapreduce.rb
CHANGED
@@ -19,12 +19,12 @@ module Couchup
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.reduce(*params)
|
22
|
-
view({:reduce => true}, *params)
|
22
|
+
view({:reduce => true,:group => true}, *params)
|
23
23
|
end
|
24
24
|
|
25
25
|
private
|
26
26
|
def self.view(options, *params)
|
27
|
-
name = params.shift
|
27
|
+
name = params.shift.to_s
|
28
28
|
view_params = options
|
29
29
|
if params.size == 1
|
30
30
|
val = params.first
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Couchup
|
2
|
+
module ShortHands
|
3
|
+
def included(base)
|
4
|
+
%w{create drop show}.each do |action|
|
5
|
+
['view', 'db'].each { |on| base.send "#{action}_#{on}"}
|
6
|
+
end
|
7
|
+
alias :create_database :create_db
|
8
|
+
alias :drop_database :drop_db
|
9
|
+
alias :show_database :show_db
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_view(*params)
|
13
|
+
create :view, *params
|
14
|
+
end
|
15
|
+
def create_db(*params)
|
16
|
+
create :database, *params
|
17
|
+
end
|
18
|
+
|
19
|
+
def show_view(*params)
|
20
|
+
show :view, *params
|
21
|
+
end
|
22
|
+
|
23
|
+
def show_db(*params)
|
24
|
+
show :databases, *params
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_db(*params)
|
28
|
+
create :database, *params
|
29
|
+
end
|
30
|
+
|
31
|
+
def drop_view(*params)
|
32
|
+
drop :view, *params
|
33
|
+
end
|
34
|
+
|
35
|
+
def drop_db(*params)
|
36
|
+
drop :database, *params
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/couchup/version.rb
CHANGED
data/lib/couchup/view.rb
CHANGED
@@ -57,10 +57,13 @@ module Couchup
|
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
|
-
def self.
|
61
|
-
v = new(name)
|
62
|
-
|
60
|
+
def self.create_from_file(name, file_contents)
|
63
61
|
map, reduce = parse(file_contents)
|
62
|
+
create(name, map, reduce)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.create(name, map, reduce)
|
66
|
+
v = new(name)
|
64
67
|
v.map = map
|
65
68
|
v.reduce = reduce unless reduce.blank?
|
66
69
|
ap v
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Couchup
|
4
|
+
module Commands
|
5
|
+
describe Compact do
|
6
|
+
before(:all) do
|
7
|
+
reset_data!
|
8
|
+
end
|
9
|
+
describe "without any parameter" do
|
10
|
+
it "should compact current database" do
|
11
|
+
res = Compact.new.run()
|
12
|
+
res["ok"].should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should fail when on no database" do
|
16
|
+
Couchup.database = nil
|
17
|
+
begin
|
18
|
+
Compact.new.run()
|
19
|
+
fail("Expected compact to fail")
|
20
|
+
rescue ArgumentError => e
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "when database is specified" do
|
26
|
+
it "should compact specified db when on no db" do
|
27
|
+
Couchup.database = nil
|
28
|
+
res = Compact.new.run(database.name)
|
29
|
+
res["ok"].should be_true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
module Couchup
|
3
|
+
module Commands
|
4
|
+
describe Map do
|
5
|
+
before(:all) do
|
6
|
+
ddoc = {
|
7
|
+
"_id" => "_design/Rider",
|
8
|
+
"views" => {
|
9
|
+
"all" => {
|
10
|
+
"map" => "function(doc){if(doc.name) emit(doc.name, 1)}",
|
11
|
+
"reduce" => "_sum"
|
12
|
+
}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
database.save_doc(ddoc)
|
16
|
+
end
|
17
|
+
after(:each) do
|
18
|
+
reset_data!
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "simple map" do
|
22
|
+
it "with no documents should return empty" do
|
23
|
+
res = Map.new.run("Rider/all")
|
24
|
+
res.size.should == 0
|
25
|
+
end
|
26
|
+
|
27
|
+
it "with documents should find all" do
|
28
|
+
5.times {|n| database.save_doc({:name => "foo_#{n}"})}
|
29
|
+
res = Map.new.run("Rider/all")
|
30
|
+
res.size.should == 5
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "map with a key" do
|
35
|
+
it "should return nothing when key is not found" do
|
36
|
+
res = Map.new.run("Rider/all", "xxx")
|
37
|
+
res.size.should == 0
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should find one" do
|
41
|
+
database.save_doc({:name => "foo"})
|
42
|
+
res = Map.new.run("Rider/all", "foo")
|
43
|
+
foo = res.first
|
44
|
+
foo["_id"].should_not be_nil
|
45
|
+
foo["_rev"].should_not be_nil
|
46
|
+
foo["name"].should == "foo"
|
47
|
+
|
48
|
+
res.size.should == 1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should find all matching" do
|
52
|
+
database.save_doc({:name => "foo"})
|
53
|
+
database.save_doc({:name => "foo"})
|
54
|
+
database.save_doc({:name => "bar"})
|
55
|
+
res = Map.new.run("Rider/all", "foo")
|
56
|
+
res.size.should == 2
|
57
|
+
names = res.collect{|r| r["name"]}.uniq
|
58
|
+
names.size.should == 1
|
59
|
+
names.should include("foo")
|
60
|
+
names.should_not include("bar")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
describe "map with multiple keys" do
|
64
|
+
it "returns all matching keys" do
|
65
|
+
database.save_doc({:name => "foo"})
|
66
|
+
database.save_doc({:name => "foo"})
|
67
|
+
database.save_doc({:name => "bar"})
|
68
|
+
res = Map.new.run("Rider/all", "foo", "bar", "tar")
|
69
|
+
res.size.should == 3
|
70
|
+
names = res.collect{|r| r["name"]}.uniq
|
71
|
+
names.size.should == 2
|
72
|
+
names.should include("foo")
|
73
|
+
names.should include("bar")
|
74
|
+
names.should_not include("tar")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns matching keys" do
|
78
|
+
database.save_doc({:name => "foo"})
|
79
|
+
database.save_doc({:name => "foo"})
|
80
|
+
database.save_doc({:name => "bar"})
|
81
|
+
|
82
|
+
res = Map.new.run("Rider/all", ["bar", "tar"])
|
83
|
+
res.size.should == 1
|
84
|
+
end
|
85
|
+
end
|
86
|
+
describe "startkey and end key " do
|
87
|
+
it "returns matching keys from start" do
|
88
|
+
database.save_doc({:name => "foo"})
|
89
|
+
res = Map.new.run("Rider/all", {:startkey => "foo"})
|
90
|
+
res.size.should == 1
|
91
|
+
end
|
92
|
+
|
93
|
+
it "returns matching keys from start" do
|
94
|
+
database.save_doc({:name => "foo"})
|
95
|
+
database.save_doc({:name => "bar"})
|
96
|
+
res = Map.new.run("Rider/all", {:startkey => "bar", :endkey => 'foo'})
|
97
|
+
res.size.should == 2
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns matching keys till end" do
|
101
|
+
database.save_doc({:name => "foo"})
|
102
|
+
database.save_doc({:name => "bar"})
|
103
|
+
database.save_doc({:name => "gar"})
|
104
|
+
res = Map.new.run("Rider/all", { :endkey => 'foo'})
|
105
|
+
res.size.should == 2
|
106
|
+
names = res.collect{|r| r["name"]}
|
107
|
+
names.should include "foo"
|
108
|
+
names.should include "bar"
|
109
|
+
names.should_not include "gar"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
module Couchup
|
4
|
+
module Commands
|
5
|
+
describe Use do
|
6
|
+
it "stays on the same database if db does not exist" do
|
7
|
+
Couchup.database.name.should == TEST_DATABASE
|
8
|
+
res = Use.new.run("xxxxxx")
|
9
|
+
res.should be_nil
|
10
|
+
Couchup.database.name.should == TEST_DATABASE
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
ROOT = File.expand_path("../..", __FILE__)
|
6
|
+
$LOAD_PATH.unshift(File.join(ROOT, "lib"))
|
7
|
+
require 'couchup'
|
8
|
+
|
9
|
+
|
10
|
+
# Spec stuff
|
11
|
+
require 'awesome_print'
|
12
|
+
require 'couchrest'
|
13
|
+
|
14
|
+
HOST = ENV['HOST'] || "127.0.0.1"
|
15
|
+
PORT = ENV['PORT'] || "5984"
|
16
|
+
|
17
|
+
TEST_DATABASE = 'couchup_test'
|
18
|
+
|
19
|
+
def database
|
20
|
+
@db ||= CouchRest.database!("http://#{HOST}:#{PORT}/#{TEST_DATABASE}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def reset_data!
|
24
|
+
database.documents(:include_docs => true)["rows"].collect{|r| r["doc"]}.each {|d|database.delete_doc(d) unless d["_id"] =~ /_design/}
|
25
|
+
end
|
26
|
+
|
27
|
+
def ap(*params)
|
28
|
+
# no op
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.configure do |config|
|
32
|
+
config.before(:all) do
|
33
|
+
begin
|
34
|
+
database.delete!
|
35
|
+
database.create!
|
36
|
+
Couchup::Couchup.host = HOST
|
37
|
+
Couchup::Couchup.port = PORT
|
38
|
+
Couchup::Couchup.database = TEST_DATABASE
|
39
|
+
rescue
|
40
|
+
ap "Looks like the couch db does not exist. Use HOST and or PORT env param to set the couchdb server"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
data/spec/specs.opts
ADDED
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: couchup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.1.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- V Sreekanth
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-03-
|
13
|
+
date: 2011-03-31 00:00:00 +05:30
|
14
14
|
default_executable: couchup
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -132,6 +132,7 @@ files:
|
|
132
132
|
- bin/couchup
|
133
133
|
- couchup.gemspec
|
134
134
|
- lib/couchup.rb
|
135
|
+
- lib/couchup/command_extensions.rb
|
135
136
|
- lib/couchup/commands/compact.rb
|
136
137
|
- lib/couchup/commands/connect.rb
|
137
138
|
- lib/couchup/commands/create.rb
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- lib/couchup/commands/get.rb
|
140
141
|
- lib/couchup/commands/help.rb
|
141
142
|
- lib/couchup/commands/map.rb
|
143
|
+
- lib/couchup/commands/rename.rb
|
142
144
|
- lib/couchup/commands/replicate_to.rb
|
143
145
|
- lib/couchup/commands/restart.rb
|
144
146
|
- lib/couchup/commands/show.rb
|
@@ -150,8 +152,15 @@ files:
|
|
150
152
|
- lib/couchup/extensions/string.rb
|
151
153
|
- lib/couchup/extensions/symbol.rb
|
152
154
|
- lib/couchup/mapreduce.rb
|
155
|
+
- lib/couchup/short_hands.rb
|
153
156
|
- lib/couchup/version.rb
|
154
157
|
- lib/couchup/view.rb
|
158
|
+
- spec/commands/compact_spec.rb
|
159
|
+
- spec/commands/map_spec.rb
|
160
|
+
- spec/commands/use_spec.rb
|
161
|
+
- spec/couchup_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
- spec/specs.opts
|
155
164
|
has_rdoc: true
|
156
165
|
homepage: http://blog.activesphere.com/introducing-couchup-an-interactive-couchdb-co
|
157
166
|
licenses: []
|
@@ -176,9 +185,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
176
185
|
requirements: []
|
177
186
|
|
178
187
|
rubyforge_project: couchup
|
179
|
-
rubygems_version: 1.
|
188
|
+
rubygems_version: 1.6.2
|
180
189
|
signing_key:
|
181
190
|
specification_version: 3
|
182
191
|
summary: Command line interface to a couchdb deployment.
|
183
|
-
test_files:
|
184
|
-
|
192
|
+
test_files:
|
193
|
+
- spec/commands/compact_spec.rb
|
194
|
+
- spec/commands/map_spec.rb
|
195
|
+
- spec/commands/use_spec.rb
|
196
|
+
- spec/couchup_spec.rb
|
197
|
+
- spec/spec_helper.rb
|
198
|
+
- spec/specs.opts
|