couchup 0.0.13 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|