sdb_service 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
|
|
1
|
+
module SdbService
|
2
|
+
class Serializer
|
3
|
+
|
4
|
+
def initialize(data)
|
5
|
+
@payload = data
|
6
|
+
@transformed_payload = nil
|
7
|
+
@valid = true
|
8
|
+
end
|
9
|
+
|
10
|
+
def serialize!
|
11
|
+
begin
|
12
|
+
@transformed_payload = serialize_payload(@payload)
|
13
|
+
@valid = true
|
14
|
+
rescue
|
15
|
+
@valid = false
|
16
|
+
@transformed_payload = @payload
|
17
|
+
end
|
18
|
+
return @transformed_payload
|
19
|
+
end
|
20
|
+
|
21
|
+
def deserialize!
|
22
|
+
begin
|
23
|
+
@transformed_payload = deserialize_payload(@payload)
|
24
|
+
rescue
|
25
|
+
@transformed_payload = @payload
|
26
|
+
end
|
27
|
+
return @transformed_payload
|
28
|
+
end
|
29
|
+
|
30
|
+
def valid?
|
31
|
+
@valid
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
@transformed_payload
|
36
|
+
end
|
37
|
+
|
38
|
+
# these methods should be overriden by the strategy that subclasses the Serializer class.
|
39
|
+
|
40
|
+
def serialize_payload
|
41
|
+
raise "override me! -- #serialize_payload"
|
42
|
+
end
|
43
|
+
|
44
|
+
def deserialize_payload
|
45
|
+
raise "override me! -- #deserialize_payload"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'sdb_service/serializer'
|
2
|
+
require 'json/pure'
|
3
|
+
|
4
|
+
module SdbService
|
5
|
+
class JsonSerializer < Serializer
|
6
|
+
|
7
|
+
def serialize_payload(payload)
|
8
|
+
JSON.generate(payload)
|
9
|
+
end
|
10
|
+
|
11
|
+
def deserialize_payload(payload)
|
12
|
+
JSON.parse(payload)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'sdb_service/serializer'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SdbService
|
5
|
+
class YamlSerializer < Serializer
|
6
|
+
|
7
|
+
def serialize_payload(payload)
|
8
|
+
YAML.dump(payload)
|
9
|
+
end
|
10
|
+
|
11
|
+
def deserialize_payload(payload)
|
12
|
+
YAML.load(payload)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,165 @@
|
|
1
|
+
require 'uuidtools'
|
2
|
+
require 'aws_sdb'
|
3
|
+
require 'sdb_service/support/constantizer'
|
4
|
+
|
5
|
+
module SdbService
|
6
|
+
|
7
|
+
class Service
|
8
|
+
|
9
|
+
include Constantizer
|
10
|
+
|
11
|
+
attr_reader :database # this is the name of the amazon SimpleDB domain.
|
12
|
+
attr_reader :serializer_format # this is a symbol representation of the serializer format.
|
13
|
+
|
14
|
+
# initialization has one required argument, and one optional argument.
|
15
|
+
# the first argument should be the name of the database on Amazon's SimpleDB servers.
|
16
|
+
# the secondary, optional argument, is the type of serialization strategy you'd like
|
17
|
+
# to use for this database.
|
18
|
+
def initialize(database, serializer = :json)
|
19
|
+
@serializer_format = serializer
|
20
|
+
load_serializer!(@serializer_format)
|
21
|
+
unless database.nil?
|
22
|
+
@database = database
|
23
|
+
self.class.create_database!(@database)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# This method just takes a ruby object, of any depth or complexity; anything you
|
28
|
+
# wish to send out to the Amazon SimpleDB service, can be sent there through this method.
|
29
|
+
# eg: SERV.put("some" => "data", "more_data" => { "here" => [1,2,3] })
|
30
|
+
#
|
31
|
+
# all data passed through the #put method is serialized into whatever format you constructed
|
32
|
+
# the data service to be aware of, however, you can pass a false in as the first argument of #put
|
33
|
+
# to have it ignore serialization entirely.
|
34
|
+
# eg: SERV.put(false, "some" => {"more" => [1,2,3]}) #=> { "some" => ["more123"]}
|
35
|
+
#
|
36
|
+
# put returns the unique identifier (UUID) of the object that was persisted into SimpleDB.
|
37
|
+
def put(*args)
|
38
|
+
data_payload, raw_payload = args
|
39
|
+
serializer_result = nil
|
40
|
+
if raw_payload.nil?
|
41
|
+
data = _parse(data_payload) do |value|
|
42
|
+
serializer_result = serializer.new(value)
|
43
|
+
serializer_result.serialize!.to_s
|
44
|
+
end
|
45
|
+
data["mime_type"] = "text/#{serializer_result.valid? ? self.serializer_format : "plain"}"
|
46
|
+
else
|
47
|
+
data = raw_payload
|
48
|
+
data["mime_type"] = "text/plain"
|
49
|
+
end
|
50
|
+
|
51
|
+
ident = self.class.generate_unique_identifier
|
52
|
+
data_store.put_attributes(self.database, ident, data)
|
53
|
+
return ident
|
54
|
+
end
|
55
|
+
|
56
|
+
# This method returns an object from Amazon SimpleDB based on its UUID identifier,
|
57
|
+
# and will also attempt to deserialize its various values from whatever serialization
|
58
|
+
# format you've specified when constructing the data service.
|
59
|
+
def get(id)
|
60
|
+
_parse(self.get!(id)) do |value|
|
61
|
+
serializer.new(value.first).deserialize!
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# This method returns an object from Amazon SimpleDB based on its UUID identifier,
|
66
|
+
# it returns the raw, unparsed data that sits at that key in the store.
|
67
|
+
def get!(id)
|
68
|
+
data_store.get_attributes(self.database, id)
|
69
|
+
end
|
70
|
+
|
71
|
+
# this method deletes an object from Amazon SimpleDB based on its UUID identifier.
|
72
|
+
def delete(id)
|
73
|
+
data_store.delete_attributes(self.database, id)
|
74
|
+
end
|
75
|
+
|
76
|
+
# this method allows you to query simple for raw information using its query language.
|
77
|
+
def query(statement)
|
78
|
+
data_store.query(self.database, statement)
|
79
|
+
end
|
80
|
+
|
81
|
+
# this method returns all of the UUIDS stored in Amazon SimpleDB for the current domain.
|
82
|
+
def all!
|
83
|
+
self.query("")
|
84
|
+
end
|
85
|
+
|
86
|
+
# this method returns all of the fully qualified, and deserialized objects stored in Amazon
|
87
|
+
# SimpleDB for the current domain.
|
88
|
+
def all
|
89
|
+
results = Hash.new
|
90
|
+
self.all![0].each do |item_name|
|
91
|
+
results[item_name] = self.get(item_name)
|
92
|
+
end
|
93
|
+
return results
|
94
|
+
end
|
95
|
+
|
96
|
+
# this method returns a list of all databases associated with this AWS account.
|
97
|
+
def self.all_databases
|
98
|
+
self.send(:data_store).list_domains[0]
|
99
|
+
end
|
100
|
+
|
101
|
+
# this method creates a new database associated with this AWS account, unless one with
|
102
|
+
# the same name already exists. returns true on success, false on failure.
|
103
|
+
def self.create_database!(database)
|
104
|
+
unless self.all_databases.include?(database)
|
105
|
+
self.send(:data_store).create_domain(database)
|
106
|
+
return true
|
107
|
+
else
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# this method destroys an existing database associated with this AWS account, unless one
|
113
|
+
# with the name specified does not exist. returns true on success, false on failure.
|
114
|
+
def self.destroy_database!(database)
|
115
|
+
if self.all_databases.include?(database)
|
116
|
+
self.send(:data_store).delete_domain(database)
|
117
|
+
return true
|
118
|
+
else
|
119
|
+
return false
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# this method can be used to reset all the data stored in an Amazon SimpleDB database associated
|
124
|
+
# with the current AWS account.
|
125
|
+
def clear!
|
126
|
+
self.class.destroy_database!(self.database)
|
127
|
+
self.class.create_database!(self.database)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# simple method for associating and activiating a serializer strategy for an
|
133
|
+
# instance of this class.
|
134
|
+
def load_serializer!(serializer)
|
135
|
+
@serializer = constantize("#{serializer}_serializer", "lib/sdb_service/serializers")
|
136
|
+
end
|
137
|
+
|
138
|
+
# accessor for serializer
|
139
|
+
def serializer
|
140
|
+
@serializer
|
141
|
+
end
|
142
|
+
|
143
|
+
# simple strategy pattern that allows a block to have access to every value in a data hash
|
144
|
+
# returned from Amazon SimpleDB. Useful for serialization/deserialization.
|
145
|
+
def _parse(data, &block)
|
146
|
+
Hash[data.collect { |k,v| [k,block.call(v)] }]
|
147
|
+
end
|
148
|
+
|
149
|
+
# accessor for AWS/SDB data service.
|
150
|
+
def self.data_store
|
151
|
+
AwsSdb::Service.new(:logger => Logger.new("/dev/null"))
|
152
|
+
end
|
153
|
+
|
154
|
+
# instance accessor for AWS/SDB data service.
|
155
|
+
def data_store
|
156
|
+
@store ||= self.class.data_store
|
157
|
+
end
|
158
|
+
|
159
|
+
# this helper method generates a random UUID for SimpleDB objects.
|
160
|
+
def self.generate_unique_identifier
|
161
|
+
UUIDTools::UUID.random_create.to_s
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module SdbService
|
2
|
+
module Constantizer
|
3
|
+
|
4
|
+
# hackish helper method for properly casting a string to a constantized class.
|
5
|
+
def constantize(klass_name, load_path)
|
6
|
+
require "#{load_path}/#{klass_name}"
|
7
|
+
eval(klass_name.gsub(/^[a-z]|\s|_+[a-z]/) { |a| a.upcase }.gsub(/\s|_/, '')) rescue nil
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
end
|
data/sdb_service.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'sdb_service/service'
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sdb_service
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Derek Perez
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-04 00:00:00 -07:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: uuidtools
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 1
|
30
|
+
- 1
|
31
|
+
version: 2.1.1
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: json_pure
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 1
|
43
|
+
- 4
|
44
|
+
- 1
|
45
|
+
version: 1.4.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: aws-sdb
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 0
|
57
|
+
- 3
|
58
|
+
- 1
|
59
|
+
version: 0.3.1
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
description: even simpler wrapper around aws_sdb, with builtin serialization.
|
63
|
+
email: derek@derekperez.com
|
64
|
+
executables: []
|
65
|
+
|
66
|
+
extensions: []
|
67
|
+
|
68
|
+
extra_rdoc_files: []
|
69
|
+
|
70
|
+
files:
|
71
|
+
- sdb_service.rb
|
72
|
+
- lib/sdb_service/serializer.rb
|
73
|
+
- lib/sdb_service/serializers/json_serializer.rb
|
74
|
+
- lib/sdb_service/serializers/yaml_serializer.rb
|
75
|
+
- lib/sdb_service/service.rb
|
76
|
+
- lib/sdb_service/support/constantizer.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://blog.derekperez.com/
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options: []
|
83
|
+
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
version: "0"
|
100
|
+
requirements: []
|
101
|
+
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 1.3.6
|
104
|
+
signing_key:
|
105
|
+
specification_version: 3
|
106
|
+
summary: even simpler wrapper around aws_sdb, with builtin serialization.
|
107
|
+
test_files: []
|
108
|
+
|