sdbport 0.0.1 → 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/.travis.yml +3 -0
- data/CHANGELOG +5 -0
- data/README.md +40 -9
- data/Rakefile +6 -0
- data/bin/sdbport +1 -1
- data/lib/sdbport/aws/simpledb.rb +40 -11
- data/lib/sdbport/cli/export.rb +41 -0
- data/lib/sdbport/cli/import.rb +41 -0
- data/lib/sdbport/cli/purge.rb +38 -0
- data/lib/sdbport/cli.rb +19 -4
- data/lib/sdbport/domain/export.rb +43 -0
- data/lib/sdbport/domain/import.rb +62 -0
- data/lib/sdbport/domain/purge.rb +32 -0
- data/lib/sdbport/domain.rb +39 -0
- data/lib/sdbport/sdbport_logger.rb +34 -0
- data/lib/sdbport/version.rb +1 -1
- data/lib/sdbport.rb +2 -0
- data/sdbport.gemspec +2 -2
- data/spec/aws/simpledb_spec.rb +78 -0
- data/spec/domain/export_spec.rb +33 -0
- data/spec/domain/import_spec.rb +42 -0
- data/spec/domain/purge_spec.rb +24 -0
- data/spec/domain_spec.rb +33 -0
- data/spec/sdbport_logger_spec.rb +23 -0
- data/spec/spec_helper.rb +28 -0
- metadata +37 -13
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
data/README.md
CHANGED
@@ -1,24 +1,55 @@
|
|
1
1
|
# Sdbport
|
2
2
|
|
3
|
-
|
3
|
+
Sdbport exports & imports data from AWS SimpleDB domains. It can be used as a class or stand alone CLI.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
|
7
|
+
gem install sdbport
|
8
8
|
|
9
|
-
|
9
|
+
## Usage
|
10
10
|
|
11
|
-
|
11
|
+
Set your AWS credentials:
|
12
12
|
|
13
|
-
|
13
|
+
```
|
14
|
+
export AWS_ACCESS_KEY_ID=key
|
15
|
+
export AWS_SECRET_ACCESS_KEY=secret
|
16
|
+
```
|
14
17
|
|
15
|
-
|
18
|
+
Export SimpleDB domain:
|
16
19
|
|
17
|
-
|
20
|
+
```
|
21
|
+
sdbport export -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY -r us-west-1 -n test -o /tmp/test-domain-dump
|
22
|
+
```
|
18
23
|
|
19
|
-
|
24
|
+
Import into new domain:
|
25
|
+
|
26
|
+
```
|
27
|
+
sdbport import -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY -r us-west-1 -n new-domain -i /tmp/test-domain-dump
|
28
|
+
```
|
29
|
+
|
30
|
+
Purge new domain:
|
31
|
+
|
32
|
+
```
|
33
|
+
sdbport purge -a $AWS_ACCESS_KEY_ID -s $AWS_SECRET_ACCESS_KEY -r us-west-1 -n new-domain
|
34
|
+
```
|
35
|
+
|
36
|
+
To list CLI subcommands:
|
37
|
+
|
38
|
+
```
|
39
|
+
sdbport -h
|
40
|
+
```
|
41
|
+
|
42
|
+
For details help on specific subcommand:
|
43
|
+
|
44
|
+
```
|
45
|
+
sdbport export -h
|
46
|
+
```
|
47
|
+
|
48
|
+
## Known Limitations
|
20
49
|
|
21
|
-
|
50
|
+
* Only performs a single query for exports, which gives it a maxmimum of 1,000 entries.
|
51
|
+
* Single serialiazed process.
|
52
|
+
* Only supports importing into empty domain.
|
22
53
|
|
23
54
|
## Contributing
|
24
55
|
|
data/Rakefile
CHANGED
data/bin/sdbport
CHANGED
data/lib/sdbport/aws/simpledb.rb
CHANGED
@@ -5,29 +5,58 @@ module Sdbport
|
|
5
5
|
class SimpleDB
|
6
6
|
|
7
7
|
def initialize(args)
|
8
|
-
access_key = args[:access_key]
|
9
|
-
secret_key = args[:secret_key]
|
10
|
-
region = args[:region]
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
@access_key = args[:access_key]
|
9
|
+
@secret_key = args[:secret_key]
|
10
|
+
@region = args[:region]
|
11
|
+
end
|
12
|
+
|
13
|
+
def domains
|
14
|
+
sdb.list_domains.body['Domains']
|
15
|
+
end
|
14
16
|
|
15
|
-
|
17
|
+
def domain_exists?(domain)
|
18
|
+
domains.include? domain
|
16
19
|
end
|
17
20
|
|
18
|
-
def
|
19
|
-
|
21
|
+
def create_domain_unless_present(domain)
|
22
|
+
sdb.create_domain(domain) unless domain_exists?(domain)
|
20
23
|
end
|
21
24
|
|
22
25
|
def select(query)
|
23
|
-
|
26
|
+
sdb.select(query).body['Items']
|
24
27
|
end
|
25
28
|
|
26
29
|
def count(domain)
|
27
|
-
body =
|
30
|
+
body = sdb.select("SELECT count(*) FROM `#{domain}`").body
|
28
31
|
body['Items']['Domain']['Count'].first.to_i
|
29
32
|
end
|
30
33
|
|
34
|
+
def domain_empty?(domain)
|
35
|
+
count(domain).zero?
|
36
|
+
end
|
37
|
+
|
38
|
+
def put_attributes(domain, key, attributes, options = {})
|
39
|
+
sdb.put_attributes domain, key, attributes, options
|
40
|
+
end
|
41
|
+
|
42
|
+
def delete_domain(domain)
|
43
|
+
sdb.delete_domain(domain)
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete(domain, key)
|
47
|
+
sdb.delete_attributes domain, key
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def sdb
|
53
|
+
options = { :aws_access_key_id => @access_key,
|
54
|
+
:aws_secret_access_key => @secret_key,
|
55
|
+
:region => @region }
|
56
|
+
|
57
|
+
@sdb ||= Fog::AWS::SimpleDB.new options
|
58
|
+
end
|
59
|
+
|
31
60
|
end
|
32
61
|
end
|
33
62
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sdbport
|
2
|
+
class CLI
|
3
|
+
class Export
|
4
|
+
|
5
|
+
def export
|
6
|
+
opts = read_options
|
7
|
+
logger = SdbportLogger.new :log_level => opts[:level]
|
8
|
+
domain = Domain.new :name => opts[:name],
|
9
|
+
:region => opts[:region],
|
10
|
+
:access_key => opts[:access_key],
|
11
|
+
:secret_key => opts[:secret_key],
|
12
|
+
:logger => logger
|
13
|
+
unless domain.export opts[:output]
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_options
|
19
|
+
Trollop::options do
|
20
|
+
version Sdbport::VERSION
|
21
|
+
banner <<-EOS
|
22
|
+
|
23
|
+
Export SimpleDB domain.
|
24
|
+
|
25
|
+
Usage:
|
26
|
+
|
27
|
+
sdbport export -a xxx -k yyy -r us-west-1 -o /tmp/file -n domain
|
28
|
+
|
29
|
+
EOS
|
30
|
+
opt :help, "Display Help"
|
31
|
+
opt :level, "Log Level", :type => :string, :default => 'info'
|
32
|
+
opt :name, "Simple DB Domain Name", :type => :string
|
33
|
+
opt :output, "Output File", :type => :string
|
34
|
+
opt :region, "AWS region", :type => :string
|
35
|
+
opt :access_key, "AWS Access Key ID", :type => :string
|
36
|
+
opt :secret_key, "AWS Secret Access Key", :type => :string
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Sdbport
|
2
|
+
class CLI
|
3
|
+
class Import
|
4
|
+
|
5
|
+
def import
|
6
|
+
opts = read_options
|
7
|
+
logger = SdbportLogger.new :log_level => opts[:level]
|
8
|
+
domain = Domain.new :name => opts[:name],
|
9
|
+
:region => opts[:region],
|
10
|
+
:access_key => opts[:access_key],
|
11
|
+
:secret_key => opts[:secret_key],
|
12
|
+
:logger => logger
|
13
|
+
unless domain.import opts[:input]
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_options
|
19
|
+
Trollop::options do
|
20
|
+
version Sdbport::VERSION
|
21
|
+
banner <<-EOS
|
22
|
+
|
23
|
+
Import SimpleDB domain.
|
24
|
+
|
25
|
+
Usage:
|
26
|
+
|
27
|
+
sdbport import -a xxx -k yyy -r us-west-1 -i /tmp/file -n domain
|
28
|
+
|
29
|
+
EOS
|
30
|
+
opt :help, "Display Help"
|
31
|
+
opt :level, "Log Level", :type => :string, :default => 'info'
|
32
|
+
opt :name, "Simple DB Domain Name", :type => :string
|
33
|
+
opt :input, "Input File", :type => :string
|
34
|
+
opt :region, "AWS region", :type => :string
|
35
|
+
opt :access_key, "AWS Access Key ID", :type => :string
|
36
|
+
opt :secret_key, "AWS Secret Access Key", :type => :string
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Sdbport
|
2
|
+
class CLI
|
3
|
+
class Purge
|
4
|
+
|
5
|
+
def purge
|
6
|
+
opts = read_options
|
7
|
+
logger = SdbportLogger.new :log_level => opts[:level]
|
8
|
+
domain = Domain.new :name => opts[:name],
|
9
|
+
:region => opts[:region],
|
10
|
+
:access_key => opts[:access_key],
|
11
|
+
:secret_key => opts[:secret_key],
|
12
|
+
:logger => logger
|
13
|
+
domain.purge
|
14
|
+
end
|
15
|
+
|
16
|
+
def read_options
|
17
|
+
Trollop::options do
|
18
|
+
version Sdbport::VERSION
|
19
|
+
banner <<-EOS
|
20
|
+
|
21
|
+
Purge all entries from a SimpleDB domain.
|
22
|
+
|
23
|
+
Usage:
|
24
|
+
|
25
|
+
sdbport purge -a xxx -k yyy -r us-west-1 -n domain
|
26
|
+
|
27
|
+
EOS
|
28
|
+
opt :help, "Display Help"
|
29
|
+
opt :level, "Log Level", :type => :string, :default => 'info'
|
30
|
+
opt :name, "Simple DB Domain Name", :type => :string
|
31
|
+
opt :region, "AWS region", :type => :string
|
32
|
+
opt :access_key, "AWS Access Key ID", :type => :string
|
33
|
+
opt :secret_key, "AWS Secret Access Key", :type => :string
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/sdbport/cli.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
require 'trollop'
|
2
|
+
require 'sdbport/cli/export'
|
3
|
+
require 'sdbport/cli/import'
|
4
|
+
require 'sdbport/cli/purge'
|
2
5
|
|
3
6
|
module Sdbport
|
4
|
-
|
5
|
-
|
7
|
+
class CLI
|
8
|
+
|
9
|
+
def start
|
10
|
+
|
6
11
|
cmd = ARGV.shift
|
7
12
|
|
8
13
|
case cmd
|
9
14
|
when 'export'
|
10
|
-
|
15
|
+
CLI::Export.new.export
|
11
16
|
when 'import'
|
12
|
-
|
17
|
+
CLI::Import.new.import
|
18
|
+
when 'purge'
|
19
|
+
CLI::Purge.new.purge
|
20
|
+
when '-v'
|
21
|
+
puts Sdbport::VERSION
|
22
|
+
else
|
23
|
+
puts "Unkown command: '#{cmd}'." unless cmd == '-h'
|
24
|
+
puts "sdbport [export|import|purge] OPTIONS"
|
25
|
+
puts "Append -h for help on specific subcommand."
|
13
26
|
end
|
27
|
+
|
14
28
|
end
|
29
|
+
|
15
30
|
end
|
16
31
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Sdbport
|
4
|
+
class Domain
|
5
|
+
class Export
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@name = args[:name]
|
9
|
+
@logger = args[:logger]
|
10
|
+
@access_key = args[:access_key]
|
11
|
+
@secret_key = args[:secret_key]
|
12
|
+
@region = args[:region]
|
13
|
+
end
|
14
|
+
|
15
|
+
def export(output)
|
16
|
+
@logger.info "Export #{@name} in #{@region} to #{output}"
|
17
|
+
file = File.open(output, 'w')
|
18
|
+
export_domain.each do |item|
|
19
|
+
file.write convert_to_string item
|
20
|
+
file.write "\n"
|
21
|
+
end
|
22
|
+
return true if file.close.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def sdb
|
28
|
+
@sdb ||= AWS::SimpleDB.new :access_key => @access_key,
|
29
|
+
:secret_key => @secret_key,
|
30
|
+
:region => @region
|
31
|
+
end
|
32
|
+
|
33
|
+
def export_domain
|
34
|
+
sdb.select "select * from `#{@name}`"
|
35
|
+
end
|
36
|
+
|
37
|
+
def convert_to_string(item)
|
38
|
+
item.to_json
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Sdbport
|
4
|
+
class Domain
|
5
|
+
class Import
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@name = args[:name]
|
9
|
+
@logger = args[:logger]
|
10
|
+
@access_key = args[:access_key]
|
11
|
+
@secret_key = args[:secret_key]
|
12
|
+
@region = args[:region]
|
13
|
+
end
|
14
|
+
|
15
|
+
def import(input)
|
16
|
+
create_domain
|
17
|
+
|
18
|
+
return false unless ensure_domain_empty
|
19
|
+
|
20
|
+
@logger.info "Importing #{@name} in #{@region} from #{input}."
|
21
|
+
|
22
|
+
file = File.open(input, 'r')
|
23
|
+
while (line = file.gets)
|
24
|
+
add_line line
|
25
|
+
end
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def create_domain
|
32
|
+
sdb.create_domain_unless_present @name
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_line(line)
|
36
|
+
line.chomp!
|
37
|
+
data = JSON.parse line
|
38
|
+
id = data.first
|
39
|
+
attributes = data.last
|
40
|
+
|
41
|
+
@logger.debug "Adding #{id} with attributes #{attributes.to_s}."
|
42
|
+
sdb.put_attributes @name, id, attributes
|
43
|
+
end
|
44
|
+
|
45
|
+
def ensure_domain_empty
|
46
|
+
if sdb.domain_empty? @name
|
47
|
+
true
|
48
|
+
else
|
49
|
+
@logger.error "Domain #{@name} in #{@region} not empty."
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def sdb
|
55
|
+
@sdb ||= AWS::SimpleDB.new :access_key => @access_key,
|
56
|
+
:secret_key => @secret_key,
|
57
|
+
:region => @region
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Sdbport
|
2
|
+
class Domain
|
3
|
+
class Purge
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@name = args[:name]
|
7
|
+
@logger = args[:logger]
|
8
|
+
@access_key = args[:access_key]
|
9
|
+
@secret_key = args[:secret_key]
|
10
|
+
@region = args[:region]
|
11
|
+
end
|
12
|
+
|
13
|
+
def purge
|
14
|
+
@logger.info "Purging #{@name} in #{@region}."
|
15
|
+
data = sdb.select "select * from `#{@name}`"
|
16
|
+
data.keys.each do |key|
|
17
|
+
@logger.debug "Deleting #{key}."
|
18
|
+
sdb.delete @name, key
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def sdb
|
25
|
+
@sdb ||= AWS::SimpleDB.new :access_key => @access_key,
|
26
|
+
:secret_key => @secret_key,
|
27
|
+
:region => @region
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'sdbport/domain/export'
|
2
|
+
require 'sdbport/domain/import'
|
3
|
+
require 'sdbport/domain/purge'
|
4
|
+
|
5
|
+
module Sdbport
|
6
|
+
class Domain
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
@args = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def import(input)
|
13
|
+
domain_import.import input
|
14
|
+
end
|
15
|
+
|
16
|
+
def export(output)
|
17
|
+
domain_export.export output
|
18
|
+
end
|
19
|
+
|
20
|
+
def purge
|
21
|
+
domain_purge.purge
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def domain_import
|
27
|
+
@domain_import ||= Domain::Import.new @args
|
28
|
+
end
|
29
|
+
|
30
|
+
def domain_export
|
31
|
+
@domain_export ||= Domain::Export.new @args
|
32
|
+
end
|
33
|
+
|
34
|
+
def domain_purge
|
35
|
+
@domain_purge ||= Domain::Purge.new @args
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'logger'
|
2
|
+
|
3
|
+
module Sdbport
|
4
|
+
class SdbportLogger
|
5
|
+
|
6
|
+
require 'forwardable'
|
7
|
+
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
def_delegators :@logger, :debug, :error, :info, :warn
|
11
|
+
|
12
|
+
def initialize(args = {})
|
13
|
+
@log_level = args[:log_level] ||= 'info'
|
14
|
+
@logger = args[:logger] ||= new_logger(args)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def new_logger(args)
|
20
|
+
Logger.new(STDOUT).tap do |l|
|
21
|
+
l.datetime_format = '%Y-%m-%dT%H:%M:%S%z'
|
22
|
+
l.formatter = proc do |severity, datetime, progname, msg|
|
23
|
+
"#{datetime} #{severity} : #{msg}\n"
|
24
|
+
end
|
25
|
+
l.level = logger_level
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger_level
|
30
|
+
Logger.const_get @log_level.upcase
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/lib/sdbport/version.rb
CHANGED
data/lib/sdbport.rb
CHANGED
data/sdbport.gemspec
CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
|
|
8
8
|
gem.version = Sdbport::VERSION
|
9
9
|
gem.authors = ["Brett Weaver"]
|
10
10
|
gem.email = ["brett@weav.net"]
|
11
|
-
gem.description = %q{
|
12
|
-
gem.summary = %q{
|
11
|
+
gem.description = %q{Import and export AWS SimpleDB domains.}
|
12
|
+
gem.summary = %q{Import and export AWS SimpleDB domains.}
|
13
13
|
gem.homepage = ""
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@fog_mock = mock 'fog'
|
7
|
+
@body_stub = mock 'body'
|
8
|
+
Fog::AWS::SimpleDB.should_receive(:new).
|
9
|
+
with(:aws_access_key_id => 'the-key',
|
10
|
+
:aws_secret_access_key => 'the-secret',
|
11
|
+
:region => 'us-west-1').
|
12
|
+
and_return @fog_mock
|
13
|
+
@sdb = Sdbport::AWS::SimpleDB.new :access_key => 'the-key',
|
14
|
+
:secret_key => 'the-secret',
|
15
|
+
:region => 'us-west-1'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should list the domains in simples db" do
|
19
|
+
@fog_mock.stub :list_domains => @body_stub
|
20
|
+
@body_stub.should_receive(:body).
|
21
|
+
and_return 'Domains' => ['domain1']
|
22
|
+
@sdb.domains.should == ['domain1']
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should create a new domain when it does not exist" do
|
26
|
+
@fog_mock.stub :list_domains => @body_stub
|
27
|
+
@body_stub.stub :body => { 'Domains' => [] }
|
28
|
+
@fog_mock.should_receive(:create_domain).with('new_domain')
|
29
|
+
@sdb.create_domain_unless_present('new_domain')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not create a new domain when already exists" do
|
33
|
+
@fog_mock.stub :list_domains => @body_stub
|
34
|
+
@body_stub.stub :body => { 'Domains' => ['new_domain'] }
|
35
|
+
@fog_mock.should_receive(:create_domain).exactly(0).times
|
36
|
+
@sdb.create_domain_unless_present('new_domain')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should destroy the specified domain" do
|
40
|
+
@fog_mock.should_receive(:delete_domain).with('new_domain')
|
41
|
+
@sdb.delete_domain('new_domain')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should update the attributes for an item" do
|
45
|
+
@fog_mock.should_receive(:put_attributes).with('domain', 'key', {'key' => 'value'}, { "option" => "123" })
|
46
|
+
@sdb.put_attributes('domain', 'key', {'key' => 'value'}, { "option" => "123" })
|
47
|
+
end
|
48
|
+
|
49
|
+
context "testing counts" do
|
50
|
+
it "should count the number of entries in the domain" do
|
51
|
+
data = { 'Items' => { 'Domain' => { 'Count' => ['1'] } } }
|
52
|
+
@fog_mock.should_receive(:select).
|
53
|
+
with('SELECT count(*) FROM `domain`').
|
54
|
+
and_return @body_stub
|
55
|
+
@body_stub.stub :body => data
|
56
|
+
@sdb.count('domain').should == 1
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return true if no entries for the domain" do
|
60
|
+
data = { 'Items' => { 'Domain' => { 'Count' => ['0'] } } }
|
61
|
+
@fog_mock.should_receive(:select).
|
62
|
+
with('SELECT count(*) FROM `domain`').
|
63
|
+
and_return @body_stub
|
64
|
+
@body_stub.stub :body => data
|
65
|
+
@sdb.domain_empty?('domain').should be_true
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return false if entries exist for the domain" do
|
69
|
+
data = { 'Items' => { 'Domain' => { 'Count' => ['50'] } } }
|
70
|
+
@fog_mock.should_receive(:select).
|
71
|
+
with('SELECT count(*) FROM `domain`').
|
72
|
+
and_return @body_stub
|
73
|
+
@body_stub.stub :body => data
|
74
|
+
@sdb.domain_empty?('domain').should be_false
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
before do
|
5
|
+
@logger_stub = logger_stub
|
6
|
+
@sdb_mock = sdb_mock
|
7
|
+
@file_mock = mock 'file'
|
8
|
+
@export = Sdbport::Domain::Export.new :name => 'name',
|
9
|
+
:logger => @logger_stub,
|
10
|
+
:access_key => 'the-key',
|
11
|
+
:secret_key => 'the-secret',
|
12
|
+
:region => 'us-west-1'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should export the domain to the given output" do
|
16
|
+
File.should_receive(:open).with('/tmp/file', 'w').
|
17
|
+
and_return @file_mock
|
18
|
+
data = { 'item1' =>
|
19
|
+
{ 'attribute' => [ 'value' ] },
|
20
|
+
'item2' =>
|
21
|
+
{ 'attribute' => [ 'different' ] }
|
22
|
+
}
|
23
|
+
@sdb_mock.should_receive(:select).
|
24
|
+
with('select * from `name`').
|
25
|
+
and_return data
|
26
|
+
@file_mock.should_receive(:write).with("[\"item1\",{\"attribute\":[\"value\"]}]")
|
27
|
+
@file_mock.should_receive(:write).with("[\"item2\",{\"attribute\":[\"different\"]}]")
|
28
|
+
@file_mock.should_receive(:write).with("\n").exactly(2).times
|
29
|
+
@file_mock.should_receive(:close).and_return nil
|
30
|
+
@export.export('/tmp/file').should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
before do
|
5
|
+
@logger_mock = logger_mock
|
6
|
+
@sdb_mock = sdb_mock
|
7
|
+
@file_mock = mock 'file'
|
8
|
+
@import = Sdbport::Domain::Import.new :name => 'name',
|
9
|
+
:logger => @logger_mock,
|
10
|
+
:access_key => 'the-key',
|
11
|
+
:secret_key => 'the-secret',
|
12
|
+
:region => 'us-west-1'
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when successful" do
|
16
|
+
it "should import from the given input" do
|
17
|
+
@line = '["item", {"key":["val1", "val2"]}]'
|
18
|
+
@sdb_mock.should_receive(:create_domain_unless_present).
|
19
|
+
with('name')
|
20
|
+
@sdb_mock.should_receive(:domain_empty?).with('name').
|
21
|
+
and_return true
|
22
|
+
File.should_receive(:open).with('/tmp/file', 'r').
|
23
|
+
and_return @file_mock
|
24
|
+
@file_mock.should_receive(:gets).and_return @line
|
25
|
+
@sdb_mock.should_receive(:put_attributes).
|
26
|
+
with("name", "item", {"key"=>["val1", "val2"]})
|
27
|
+
@file_mock.should_receive(:gets).and_return nil
|
28
|
+
@import.import('/tmp/file').should be_true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
context "when unsuccessful" do
|
32
|
+
it "should return false if the domain is not empty" do
|
33
|
+
@sdb_mock.should_receive(:create_domain_unless_present).
|
34
|
+
with('name')
|
35
|
+
@sdb_mock.should_receive(:domain_empty?).with('name').
|
36
|
+
and_return false
|
37
|
+
@logger_mock.should_receive(:error)
|
38
|
+
@import.import('/tmp/file').should be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
before do
|
5
|
+
@logger_stub = logger_stub
|
6
|
+
@sdb_mock = sdb_mock
|
7
|
+
@purge = Sdbport::Domain::Purge.new :name => 'name',
|
8
|
+
:logger => @logger_stub,
|
9
|
+
:access_key => 'the-key',
|
10
|
+
:secret_key => 'the-secret',
|
11
|
+
:region => 'us-west-1'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should puge the given domain" do
|
15
|
+
result = { 'item1' =>
|
16
|
+
{ 'attribute' => [ 'value' ] }
|
17
|
+
}
|
18
|
+
@sdb_mock.should_receive(:select).
|
19
|
+
with('select * from `name`').
|
20
|
+
and_return result
|
21
|
+
@sdb_mock.should_receive(:delete).with 'name', 'item1'
|
22
|
+
@purge.purge
|
23
|
+
end
|
24
|
+
end
|
data/spec/domain_spec.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
before do
|
5
|
+
@mock = mock
|
6
|
+
@domain = Sdbport::Domain.new :args1 => 'val1'
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should call domain_import from the given input" do
|
10
|
+
Sdbport::Domain::Import.should_receive(:new).
|
11
|
+
with(:args1 => 'val1').
|
12
|
+
and_return @mock
|
13
|
+
@mock.should_receive(:import).with('/tmp/file').
|
14
|
+
and_return true
|
15
|
+
@domain.import('/tmp/file').should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should call domain_export from the given output" do
|
19
|
+
Sdbport::Domain::Export.should_receive(:new).
|
20
|
+
with(:args1 => 'val1').
|
21
|
+
and_return @mock
|
22
|
+
@mock.should_receive(:export).with('/tmp/file').
|
23
|
+
and_return true
|
24
|
+
@domain.export('/tmp/file').should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should call domain_purge" do
|
28
|
+
Sdbport::Domain::Purge.stub :new => @mock
|
29
|
+
@mock.should_receive(:purge).and_return true
|
30
|
+
@domain.purge.should be_true
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sdbport do
|
4
|
+
|
5
|
+
it "should create a new logger object from the hash passed as :logger" do
|
6
|
+
logger_mock = mock 'logger'
|
7
|
+
logger_mock.should_receive(:info).with 'a message'
|
8
|
+
logger = Sdbport::SdbportLogger.new :logger => logger_mock
|
9
|
+
logger.info 'a message'
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should create a new logger object when one is not passed" do
|
13
|
+
logger_mock = mock 'logger'
|
14
|
+
Logger.should_receive(:new).with(STDOUT).and_return logger_mock
|
15
|
+
logger_mock.should_receive(:info).with 'a message'
|
16
|
+
logger_mock.should_receive(:datetime_format=).with '%Y-%m-%dT%H:%M:%S%z'
|
17
|
+
logger_mock.should_receive(:formatter=)
|
18
|
+
logger_mock.should_receive(:level=).with 1
|
19
|
+
logger = Sdbport::SdbportLogger.new
|
20
|
+
logger.info 'a message'
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'sdbport'
|
5
|
+
|
6
|
+
def sdb_mock
|
7
|
+
sdb_mock = mock 'simpledb'
|
8
|
+
Sdbport::AWS::SimpleDB.should_receive(:new).
|
9
|
+
with(:access_key => 'the-key',
|
10
|
+
:secret_key => 'the-secret',
|
11
|
+
:region => 'us-west-1').
|
12
|
+
and_return sdb_mock
|
13
|
+
sdb_mock
|
14
|
+
end
|
15
|
+
|
16
|
+
def logger_mock
|
17
|
+
logger_mock = mock 'logger'
|
18
|
+
logger_mock.stub :info => true, :debug => true
|
19
|
+
logger_mock
|
20
|
+
end
|
21
|
+
|
22
|
+
def logger_stub
|
23
|
+
stub 'logger_stub', :info => true, :debug => true
|
24
|
+
end
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
#spec config
|
28
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sdbport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &70332196552280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70332196552280
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: fog
|
27
|
-
requirement: &
|
27
|
+
requirement: &70332196551760 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70332196551760
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: trollop
|
38
|
-
requirement: &
|
38
|
+
requirement: &70332196551200 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,8 +43,8 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
-
description:
|
46
|
+
version_requirements: *70332196551200
|
47
|
+
description: Import and export AWS SimpleDB domains.
|
48
48
|
email:
|
49
49
|
- brett@weav.net
|
50
50
|
executables:
|
@@ -54,6 +54,8 @@ extra_rdoc_files: []
|
|
54
54
|
files:
|
55
55
|
- .gitignore
|
56
56
|
- .rvmrc
|
57
|
+
- .travis.yml
|
58
|
+
- CHANGELOG
|
57
59
|
- Gemfile
|
58
60
|
- LICENSE.txt
|
59
61
|
- README.md
|
@@ -63,8 +65,23 @@ files:
|
|
63
65
|
- lib/sdbport/aws.rb
|
64
66
|
- lib/sdbport/aws/simpledb.rb
|
65
67
|
- lib/sdbport/cli.rb
|
68
|
+
- lib/sdbport/cli/export.rb
|
69
|
+
- lib/sdbport/cli/import.rb
|
70
|
+
- lib/sdbport/cli/purge.rb
|
71
|
+
- lib/sdbport/domain.rb
|
72
|
+
- lib/sdbport/domain/export.rb
|
73
|
+
- lib/sdbport/domain/import.rb
|
74
|
+
- lib/sdbport/domain/purge.rb
|
75
|
+
- lib/sdbport/sdbport_logger.rb
|
66
76
|
- lib/sdbport/version.rb
|
67
77
|
- sdbport.gemspec
|
78
|
+
- spec/aws/simpledb_spec.rb
|
79
|
+
- spec/domain/export_spec.rb
|
80
|
+
- spec/domain/import_spec.rb
|
81
|
+
- spec/domain/purge_spec.rb
|
82
|
+
- spec/domain_spec.rb
|
83
|
+
- spec/sdbport_logger_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
68
85
|
homepage: ''
|
69
86
|
licenses: []
|
70
87
|
post_install_message:
|
@@ -79,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
79
96
|
version: '0'
|
80
97
|
segments:
|
81
98
|
- 0
|
82
|
-
hash:
|
99
|
+
hash: 3221497568157798114
|
83
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
101
|
none: false
|
85
102
|
requirements:
|
@@ -88,11 +105,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
105
|
version: '0'
|
89
106
|
segments:
|
90
107
|
- 0
|
91
|
-
hash:
|
108
|
+
hash: 3221497568157798114
|
92
109
|
requirements: []
|
93
110
|
rubyforge_project:
|
94
111
|
rubygems_version: 1.8.16
|
95
112
|
signing_key:
|
96
113
|
specification_version: 3
|
97
|
-
summary:
|
98
|
-
test_files:
|
114
|
+
summary: Import and export AWS SimpleDB domains.
|
115
|
+
test_files:
|
116
|
+
- spec/aws/simpledb_spec.rb
|
117
|
+
- spec/domain/export_spec.rb
|
118
|
+
- spec/domain/import_spec.rb
|
119
|
+
- spec/domain/purge_spec.rb
|
120
|
+
- spec/domain_spec.rb
|
121
|
+
- spec/sdbport_logger_spec.rb
|
122
|
+
- spec/spec_helper.rb
|