rpc-mapper 0.0.2 → 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/Rakefile +13 -4
- data/lib/rpc_mapper/adapters/abstract_adapter.rb +31 -12
- data/lib/rpc_mapper/adapters/bertrpc_adapter.rb +19 -1
- data/lib/rpc_mapper/adapters/restful_http_adapter.rb +91 -0
- data/lib/rpc_mapper/adapters.rb +1 -0
- data/lib/rpc_mapper/associations/external.rb +1 -1
- data/lib/rpc_mapper/base.rb +56 -63
- data/lib/rpc_mapper/cacheable.rb +1 -1
- data/lib/rpc_mapper/persistence.rb +47 -0
- data/lib/rpc_mapper/serialization.rb +1 -1
- data/lib/rpc_mapper/version.rb +2 -2
- data/lib/rpc_mapper.rb +19 -2
- metadata +5 -5
- data/lib/rpc_mapper/config_options.rb +0 -41
- data/lib/rpc_mapper/mutable.rb +0 -138
data/Rakefile
CHANGED
@@ -30,10 +30,19 @@ Rake::GemPackageTask.new(spec) do |pkg|
|
|
30
30
|
pkg.gem_spec = spec
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
[:rails2, :rails3].each do |name|
|
34
|
+
|
35
|
+
Rake::TestTask.new("test_#{name}") do |t|
|
36
|
+
t.libs << 'test'
|
37
|
+
t.ruby_opts << "-r load_#{name}"
|
38
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
39
|
+
t.verbose = true
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Test all gem versions"
|
45
|
+
task :test => [:test_rails2, :test_rails3] do
|
37
46
|
end
|
38
47
|
|
39
48
|
begin
|
@@ -4,33 +4,52 @@ module RPCMapper::Adapters
|
|
4
4
|
class AbstractAdapter
|
5
5
|
include RPCMapper::Logger
|
6
6
|
|
7
|
-
attr_accessor :
|
7
|
+
attr_accessor :config
|
8
|
+
attr_reader :type
|
8
9
|
@@registered_adapters ||= {}
|
9
10
|
|
10
|
-
def initialize(
|
11
|
-
@
|
11
|
+
def initialize(type, config)
|
12
|
+
@type = type.to_sym
|
13
|
+
@configuration_contexts = config.is_a?(Array) ? config : [config]
|
12
14
|
end
|
13
15
|
|
14
|
-
def self.create(type,
|
15
|
-
|
16
|
-
|
16
|
+
def self.create(type, config)
|
17
|
+
klass = type ? @@registered_adapters[type.to_sym] : self
|
18
|
+
klass.new(type, config)
|
17
19
|
end
|
18
20
|
|
19
|
-
def
|
20
|
-
|
21
|
+
def extend_adapter(config)
|
22
|
+
self.class.create(self.type, @configuration_contexts + [*config])
|
21
23
|
end
|
22
24
|
|
23
|
-
def
|
24
|
-
|
25
|
+
def config
|
26
|
+
@config ||= build_configuration
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
"
|
29
|
+
def read(options)
|
30
|
+
raise NotImplementedError, "You must not use the abstract adapter. Implement an adapter that extends the RPCMapper::Adapters::Abstract::Base class and overrides this method."
|
31
|
+
end
|
32
|
+
|
33
|
+
def write(object)
|
34
|
+
raise NotImplementedError, "You must not use the abstract adapter. Implement an adapter that extends the RPCMapper::Adapters::Abstract::Base class and overrides this method."
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(object)
|
38
|
+
raise NotImplementedError, "You must not use the abstract adapter. Implement an adapter that extends the RPCMapper::Adapters::Abstract::Base class and overrides this method."
|
29
39
|
end
|
30
40
|
|
31
41
|
def self.register_as(name)
|
32
42
|
@@registered_adapters[name.to_sym] = self
|
33
43
|
end
|
34
44
|
|
45
|
+
private
|
46
|
+
|
47
|
+
# TRP: Run each configure block in order of class hierarchy / definition and merge the results.
|
48
|
+
def build_configuration
|
49
|
+
@configuration_contexts.collect do |config_block|
|
50
|
+
config_block.is_a?(Hash) ? config_block : OpenStruct.new.tap { |os| config_block.call(os) }.marshal_dump
|
51
|
+
end.inject({}) { |sum, config| sum.merge(config) }
|
52
|
+
end
|
53
|
+
|
35
54
|
end
|
36
55
|
end
|
@@ -1,9 +1,27 @@
|
|
1
|
+
autoload :BERTRPC, 'bertrpc'
|
2
|
+
|
1
3
|
module RPCMapper::Adapters
|
2
4
|
class BERTRPCAdapter < RPCMapper::Adapters::AbstractAdapter
|
3
5
|
register_as :bertrpc
|
4
6
|
|
7
|
+
@@service_pool ||= {}
|
8
|
+
|
5
9
|
def service
|
6
|
-
|
10
|
+
@@service_pool["#{config[:host]}:#{config[:port]}"] ||= BERTRPC::Service.new(self.config[:host], self.config[:port])
|
11
|
+
end
|
12
|
+
|
13
|
+
def read(options)
|
14
|
+
log(options, "RPC #{config[:service]}") { self.service.call.send(self.namespace).send(self.service_name, options.merge(config[:default_options] || {})) }
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def namespace
|
20
|
+
self.config[:namespace]
|
21
|
+
end
|
22
|
+
|
23
|
+
def service_name
|
24
|
+
self.config[:service]
|
7
25
|
end
|
8
26
|
|
9
27
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
autoload :Net, 'net/http'
|
2
|
+
autoload :URI, 'uri'
|
3
|
+
|
4
|
+
module RPCMapper::Adapters
|
5
|
+
class RestfulHTTPAdapter < RPCMapper::Adapters::AbstractAdapter
|
6
|
+
register_as :restful_http
|
7
|
+
|
8
|
+
def write(object)
|
9
|
+
params = build_params_from_attributes(object)
|
10
|
+
object.new_record? ? post_http(object, params) : put_http(object, params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def delete(object)
|
14
|
+
delete_http(object)
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def post_http(object, params)
|
20
|
+
http_call(object, :post, params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def put_http(object, params)
|
24
|
+
http_call(object, :put, params)
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete_http(object)
|
28
|
+
http_call(object, :delete, self.config[:default_options])
|
29
|
+
end
|
30
|
+
|
31
|
+
def http_call(object, method, params={})
|
32
|
+
request_klass = case method
|
33
|
+
when :post then Net::HTTP::Post
|
34
|
+
when :put then Net::HTTP::Put
|
35
|
+
when :delete then Net::HTTP::Delete
|
36
|
+
end
|
37
|
+
|
38
|
+
req_uri = self.build_uri(object, method)
|
39
|
+
|
40
|
+
request = if method == :delete
|
41
|
+
request = request_klass.new([req_uri.path, req_uri.query].join('?'))
|
42
|
+
else
|
43
|
+
request = request_klass.new(req_uri.path)
|
44
|
+
request.set_form_data(params) unless method == :delete
|
45
|
+
request
|
46
|
+
end
|
47
|
+
|
48
|
+
self.log(params, "#{method.to_s.upcase} #{req_uri}") do
|
49
|
+
@last_response = Net::HTTP.new(req_uri.host, req_uri.port).start { |http| http.request(request) }
|
50
|
+
end
|
51
|
+
parse_response_code(@last_response)
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_response_code(response)
|
55
|
+
case response
|
56
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
57
|
+
true
|
58
|
+
else
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_params_from_attributes(object)
|
64
|
+
if self.config[:post_body_wrapper]
|
65
|
+
params = self.config[:default_options] || {}
|
66
|
+
|
67
|
+
object.attributes.each do |attribute, value|
|
68
|
+
params.merge!({"#{self.config[:post_body_wrapper]}[#{attribute}]" => value})
|
69
|
+
end
|
70
|
+
|
71
|
+
params
|
72
|
+
else
|
73
|
+
@attributes
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def build_uri(object, method)
|
78
|
+
url = [self.config[:host].gsub(%r{/$}, ''), self.config[:service]]
|
79
|
+
url << object.id unless object.new_record?
|
80
|
+
uri = URI.parse "#{url.join('/')}#{self.config[:format]}"
|
81
|
+
|
82
|
+
# TRP: method DELETE has no POST body so we have to append any default options onto the query string
|
83
|
+
if method == :delete
|
84
|
+
uri.query = (self.config[:default_options] || {}).collect { |key, value| "#{key}=#{value}" }.join('&')
|
85
|
+
end
|
86
|
+
|
87
|
+
uri
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/lib/rpc_mapper/adapters.rb
CHANGED
@@ -40,7 +40,7 @@ module RPCMapper::Associations
|
|
40
40
|
when :belongs, :one
|
41
41
|
klass.first(query_options) if query_options[:conditions] # TRP: Only run query if conditions is not nil
|
42
42
|
when :many
|
43
|
-
klass.
|
43
|
+
klass.apply_finder_options(query_options) if query_options[:conditions] # TRP: Only apply scopes if conditions is not nil
|
44
44
|
end
|
45
45
|
instance_variable_set(cache_ivar, cached_value)
|
46
46
|
end
|
data/lib/rpc_mapper/base.rb
CHANGED
@@ -1,24 +1,5 @@
|
|
1
|
-
# TRP: Cherry pick some goodies from active_support
|
2
|
-
require 'active_support/core_ext/array'
|
3
|
-
begin
|
4
|
-
require 'active_support/core_ext/duplicable' #ActiveSupport 2.3.5
|
5
|
-
rescue LoadError => exception
|
6
|
-
require 'active_support/core_ext/object/duplicable' #ActiveSupport 3.0.0.RC
|
7
|
-
end
|
8
|
-
require 'active_support/core_ext/class/inheritable_attributes'
|
9
|
-
require 'active_support/core_ext/hash/deep_merge'
|
10
|
-
require 'active_support/core_ext/module/delegation'
|
11
|
-
Hash.send(:include, ActiveSupport::CoreExtensions::Hash::DeepMerge) unless Hash.new.respond_to?(:deep_merge)
|
12
|
-
|
13
|
-
# TRP: Used for pretty logging
|
14
|
-
require 'benchmark'
|
15
|
-
|
16
|
-
# TRP: RPCMapper core_ext
|
17
|
-
require 'rpc_mapper/core_ext/kernel/singleton_class'
|
18
|
-
|
19
1
|
# TRP: RPCMapper modules
|
20
2
|
require 'rpc_mapper/errors'
|
21
|
-
require 'rpc_mapper/config_options'
|
22
3
|
require 'rpc_mapper/associations/contains'
|
23
4
|
require 'rpc_mapper/associations/external'
|
24
5
|
require 'rpc_mapper/cacheable'
|
@@ -29,7 +10,6 @@ require 'rpc_mapper/adapters'
|
|
29
10
|
|
30
11
|
|
31
12
|
class RPCMapper::Base
|
32
|
-
include RPCMapper::ConfigOptions
|
33
13
|
include RPCMapper::Associations::Contains
|
34
14
|
include RPCMapper::Associations::External
|
35
15
|
include RPCMapper::Serialization
|
@@ -38,23 +18,11 @@ class RPCMapper::Base
|
|
38
18
|
attr_accessor :attributes, :new_record
|
39
19
|
alias :new_record? :new_record
|
40
20
|
|
41
|
-
class_inheritable_accessor :
|
42
|
-
|
43
|
-
:rpc_server_port => 8000,
|
44
|
-
:service => nil,
|
45
|
-
:service_namespace => nil,
|
46
|
-
:adapter_type => nil,
|
47
|
-
# TRP: Only used if configure_mutable is called
|
48
|
-
:mutable_default_parameters => {},
|
49
|
-
:mutable_host => nil,
|
50
|
-
# TRP: This is used to append any options to the call (e.g. value to authenticate the client with the server, :app_key)
|
51
|
-
:default_options => {}
|
52
|
-
|
53
|
-
self.mutable = false
|
21
|
+
class_inheritable_accessor :read_adapter, :write_adapter, :cacheable, :defined_attributes, :scoped_methods, :declared_associations
|
22
|
+
|
54
23
|
self.cacheable = false
|
55
24
|
self.declared_associations = {}
|
56
25
|
self.defined_attributes = []
|
57
|
-
@@adapter_pool = {}
|
58
26
|
|
59
27
|
def initialize(attributes={})
|
60
28
|
self.new_record = true
|
@@ -67,25 +35,25 @@ class RPCMapper::Base
|
|
67
35
|
|
68
36
|
protected
|
69
37
|
|
70
|
-
# TRP: Common interface for setting attributes to keep things consistent
|
71
|
-
def set_attributes(attributes)
|
38
|
+
# TRP: Common interface for setting attributes to keep things consistent; if force is true the defined_attributes list will be ignored
|
39
|
+
def set_attributes(attributes, force=false)
|
72
40
|
attributes = attributes.inject({}) do |options, (key, value)|
|
73
41
|
options[key.to_s] = value
|
74
42
|
options
|
75
43
|
end
|
76
44
|
@attributes = {} if @attributes.nil?
|
77
|
-
@attributes.merge!(attributes.reject { |field, value| !self.defined_attributes.include?(field) })
|
45
|
+
@attributes.merge!(attributes.reject { |field, value| !self.defined_attributes.include?(field) && !force })
|
78
46
|
end
|
79
47
|
|
80
|
-
def set_attribute(attribute, value)
|
81
|
-
set_attributes({ attribute => value })
|
48
|
+
def set_attribute(attribute, value, force=false)
|
49
|
+
set_attributes({ attribute => value }, force)
|
82
50
|
end
|
83
51
|
|
84
52
|
# Class Methods
|
85
53
|
class << self
|
86
54
|
public
|
87
55
|
|
88
|
-
delegate :find, :first, :all, :search, :to => :scoped
|
56
|
+
delegate :find, :first, :all, :search, :apply_finder_options, :to => :scoped
|
89
57
|
delegate :select, :group, :order, :joins, :where, :having, :limit, :offset, :from, :to => :scoped
|
90
58
|
|
91
59
|
def new_from_data_store(hash)
|
@@ -121,40 +89,43 @@ class RPCMapper::Base
|
|
121
89
|
protected
|
122
90
|
|
123
91
|
def fetch_records(options={})
|
124
|
-
self.
|
92
|
+
self.read_adapter.read(options).collect { |hash| self.new_from_data_store(hash) }.compact
|
125
93
|
end
|
126
94
|
|
127
|
-
def
|
128
|
-
|
95
|
+
def read_with(adapter_type)
|
96
|
+
setup_adapter(:read, { :type => adapter_type })
|
129
97
|
end
|
130
98
|
|
131
|
-
def
|
132
|
-
if
|
133
|
-
|
99
|
+
def write_with(adapter_type)
|
100
|
+
if write_adapter
|
101
|
+
write_inheritable_attribute :write_adapter, nil if adapter_type != write_adapter.type
|
134
102
|
else
|
135
|
-
super
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
def configure(options={})
|
140
|
-
self.configure_options.each { |option| self.send("#{option}=", options[option]) if options[option] }
|
141
|
-
end
|
142
|
-
|
143
|
-
# TRP: Only pulls in mutable module if configure_mutable is called
|
144
|
-
def configure_mutable(options={})
|
145
|
-
unless mutable
|
146
|
-
self.mutable = true
|
147
|
-
|
148
103
|
# TRP: Pull in methods and libraries needed for mutable functionality
|
149
|
-
require 'rpc_mapper/
|
150
|
-
self.send(:include, RPCMapper::
|
151
|
-
self.save_mutable_configuration(options)
|
104
|
+
require 'rpc_mapper/persistence' unless defined?(RPCMapper::Persistence)
|
105
|
+
self.send(:include, RPCMapper::Persistence) unless self.class.ancestors.include?(RPCMapper::Persistence)
|
152
106
|
|
153
107
|
# TRP: Create writers if attributes are declared before configure_mutable is called
|
154
108
|
self.defined_attributes.each { |attribute| create_writer(attribute) }
|
155
109
|
# TRP: Create serialized writers if attributes are declared serialized before this call
|
156
110
|
self.serialized_attributes.each { |attribute| set_serialize_writers(attribute) }
|
157
111
|
end
|
112
|
+
setup_adapter(:write, { :type => adapter_type })
|
113
|
+
end
|
114
|
+
|
115
|
+
def configure_read(&block)
|
116
|
+
configure_adapter(:read, &block)
|
117
|
+
end
|
118
|
+
|
119
|
+
def configure_write(&block)
|
120
|
+
configure_adapter(:write, &block)
|
121
|
+
end
|
122
|
+
|
123
|
+
def method_missing(method, *args, &block)
|
124
|
+
if scoped.dynamic_finder_method(method)
|
125
|
+
scoped.send(method, *args, &block)
|
126
|
+
else
|
127
|
+
super
|
128
|
+
end
|
158
129
|
end
|
159
130
|
|
160
131
|
def configure_cacheable(options={})
|
@@ -176,7 +147,7 @@ class RPCMapper::Base
|
|
176
147
|
end
|
177
148
|
|
178
149
|
# TRP: Setup the writers if mutable is set
|
179
|
-
create_writer(attribute) if self.
|
150
|
+
create_writer(attribute) if self.write_adapter
|
180
151
|
|
181
152
|
end
|
182
153
|
end
|
@@ -198,6 +169,28 @@ class RPCMapper::Base
|
|
198
169
|
self.scoped_methods.last
|
199
170
|
end
|
200
171
|
|
172
|
+
private
|
173
|
+
|
174
|
+
def setup_adapter(mode, config)
|
175
|
+
current_adapter = read_inheritable_attribute :"#{mode}_adapter"
|
176
|
+
type = config[:type] if config.is_a?(Hash)
|
177
|
+
|
178
|
+
new_adapter = if current_adapter
|
179
|
+
current_adapter.extend_adapter(config)
|
180
|
+
else
|
181
|
+
RPCMapper::Adapters::AbstractAdapter.create(type, config)
|
182
|
+
end
|
183
|
+
|
184
|
+
write_inheritable_attribute :"#{mode}_adapter", new_adapter
|
185
|
+
end
|
186
|
+
|
187
|
+
def configure_adapter(mode, &block)
|
188
|
+
raise ArgumentError, "A block must be passed to configure_#{mode} method." unless block_given?
|
189
|
+
raise ArgumentError, "You must first define an adapter before configuring it. Use #{mode}_with :adapter_type." unless self.send(:"#{mode}_adapter")
|
190
|
+
|
191
|
+
setup_adapter(mode, block)
|
192
|
+
end
|
193
|
+
|
201
194
|
end
|
202
195
|
|
203
196
|
end
|
data/lib/rpc_mapper/cacheable.rb
CHANGED
@@ -16,7 +16,7 @@ module RPCMapper::Cacheable
|
|
16
16
|
cache_hit = self.cacheable.read(key)
|
17
17
|
|
18
18
|
if cache_hit
|
19
|
-
self.
|
19
|
+
self.read_adapter.log(options, "CACHE")
|
20
20
|
cache_hit.each { |fv| fv.fresh = false.freeze }
|
21
21
|
cache_hit
|
22
22
|
else
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module RPCMapper::Persistence
|
2
|
+
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
protected
|
6
|
+
|
7
|
+
def create_writer(attribute)
|
8
|
+
define_method("#{attribute}=") do |value|
|
9
|
+
self[attribute] = value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
|
18
|
+
def []=(attribute, value)
|
19
|
+
set_attribute(attribute, value)
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes=(attributes)
|
23
|
+
set_attributes(attributes)
|
24
|
+
end
|
25
|
+
|
26
|
+
def save
|
27
|
+
write_adapter.write(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_attributes(attributes)
|
31
|
+
self.attributes = attributes
|
32
|
+
save
|
33
|
+
end
|
34
|
+
|
35
|
+
def destroy
|
36
|
+
write_adapter.delete(self)
|
37
|
+
end
|
38
|
+
alias :delete :destroy
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.included(receiver)
|
43
|
+
receiver.extend ClassMethods
|
44
|
+
receiver.send :include, InstanceMethods
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/lib/rpc_mapper/version.rb
CHANGED
data/lib/rpc_mapper.rb
CHANGED
@@ -1,5 +1,22 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
# TRP: Cherry pick some goodies from active_support
|
2
|
+
require 'active_support/core_ext/array'
|
3
|
+
require 'active_support/core_ext/class/inheritable_attributes'
|
4
|
+
require 'active_support/core_ext/hash/deep_merge'
|
5
|
+
begin
|
6
|
+
require 'active_support/core_ext/duplicable' #ActiveSupport 2.3.x
|
7
|
+
Hash.send(:include, ActiveSupport::CoreExtensions::Hash::DeepMerge) unless Hash.instance_methods.include?('deep_merge')
|
8
|
+
rescue LoadError => exception
|
9
|
+
require 'active_support/core_ext/object/duplicable' #ActiveSupport 3.0.x
|
10
|
+
end
|
11
|
+
require 'active_support/core_ext/module/delegation'
|
12
|
+
|
13
|
+
# TRP: Used for pretty logging
|
14
|
+
autoload :Benchmark, 'benchmark'
|
15
|
+
|
16
|
+
require 'ostruct'
|
17
|
+
|
18
|
+
# TRP: RPCMapper core_ext
|
19
|
+
require 'rpc_mapper/core_ext/kernel/singleton_class'
|
3
20
|
|
4
21
|
module RPCMapper
|
5
22
|
@@log_file = nil
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Travis Petticrew
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-26 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- Rakefile
|
126
126
|
- lib/rpc_mapper/adapters/abstract_adapter.rb
|
127
127
|
- lib/rpc_mapper/adapters/bertrpc_adapter.rb
|
128
|
+
- lib/rpc_mapper/adapters/restful_http_adapter.rb
|
128
129
|
- lib/rpc_mapper/adapters.rb
|
129
130
|
- lib/rpc_mapper/associations/common.rb
|
130
131
|
- lib/rpc_mapper/associations/contains.rb
|
@@ -133,11 +134,10 @@ files:
|
|
133
134
|
- lib/rpc_mapper/cacheable/entry.rb
|
134
135
|
- lib/rpc_mapper/cacheable/store.rb
|
135
136
|
- lib/rpc_mapper/cacheable.rb
|
136
|
-
- lib/rpc_mapper/config_options.rb
|
137
137
|
- lib/rpc_mapper/core_ext/kernel/singleton_class.rb
|
138
138
|
- lib/rpc_mapper/errors.rb
|
139
139
|
- lib/rpc_mapper/logger.rb
|
140
|
-
- lib/rpc_mapper/
|
140
|
+
- lib/rpc_mapper/persistence.rb
|
141
141
|
- lib/rpc_mapper/relation/finder_methods.rb
|
142
142
|
- lib/rpc_mapper/relation/query_methods.rb
|
143
143
|
- lib/rpc_mapper/relation.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module RPCMapper
|
2
|
-
|
3
|
-
module ConfigOptions
|
4
|
-
module ClassMethods
|
5
|
-
|
6
|
-
def config_options(options={})
|
7
|
-
options.each do |option, default_value|
|
8
|
-
class_eval do
|
9
|
-
self.configure_options << option
|
10
|
-
class_inheritable_accessor option
|
11
|
-
self.send "#{option}=", default_value
|
12
|
-
end
|
13
|
-
# TRP: We run a direct string eval on the class because we cannot get a closure on the class << self scope
|
14
|
-
# We need that in order to use our option variable to define a class method of the same name.
|
15
|
-
self.class_eval <<-EOS
|
16
|
-
def self.#{option} # def self.my_awesome_option
|
17
|
-
val = read_inheritable_attribute(:#{option}) # val = read_inheritable_attribute(:my_awesome_option)
|
18
|
-
val.is_a?(Proc) ? write_inheritable_attribute(:#{option}, val.call) : val # val.is_a?(Proc) ? write_inheritable_attribute(:my_awesome_option, val.call) : val
|
19
|
-
end # end
|
20
|
-
EOS
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
module InstanceMethods
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.included(receiver)
|
31
|
-
receiver.class_eval do
|
32
|
-
class_inheritable_accessor :configure_options
|
33
|
-
self.configure_options = []
|
34
|
-
end
|
35
|
-
|
36
|
-
receiver.extend ClassMethods
|
37
|
-
receiver.send :include, InstanceMethods
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
data/lib/rpc_mapper/mutable.rb
DELETED
@@ -1,138 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
module RPCMapper
|
5
|
-
|
6
|
-
module Mutable
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
|
10
|
-
protected
|
11
|
-
|
12
|
-
def save_mutable_configuration(options={})
|
13
|
-
self.mutable_service = options[:service] || self.service
|
14
|
-
self.mutable_post_body_wrapper = options[:post_body_wrapper]
|
15
|
-
end
|
16
|
-
|
17
|
-
def create_writer(attribute)
|
18
|
-
define_method("#{attribute}=") do |value|
|
19
|
-
self[attribute] = value
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
|
26
|
-
module InstanceMethods
|
27
|
-
|
28
|
-
def []=(attribute, value)
|
29
|
-
set_attribute(attribute, value)
|
30
|
-
end
|
31
|
-
|
32
|
-
def attributes=(attributes)
|
33
|
-
set_attributes(attributes)
|
34
|
-
end
|
35
|
-
|
36
|
-
def save
|
37
|
-
new_record? ? post_http(build_params_from_attributes) : put_http(build_params_from_attributes)
|
38
|
-
end
|
39
|
-
|
40
|
-
def update_attributes(attributes)
|
41
|
-
self.attributes = attributes
|
42
|
-
save
|
43
|
-
end
|
44
|
-
|
45
|
-
def destroy
|
46
|
-
delete_http
|
47
|
-
end
|
48
|
-
alias :delete :destroy
|
49
|
-
|
50
|
-
|
51
|
-
protected
|
52
|
-
|
53
|
-
|
54
|
-
def post_http(params)
|
55
|
-
http_call(:post, params)
|
56
|
-
end
|
57
|
-
|
58
|
-
def put_http(params)
|
59
|
-
http_call(:put, params)
|
60
|
-
end
|
61
|
-
|
62
|
-
def delete_http
|
63
|
-
http_call(:delete, self.mutable_default_parameters)
|
64
|
-
end
|
65
|
-
|
66
|
-
def http_call(method, params={})
|
67
|
-
request_klass = case method
|
68
|
-
when :post then Net::HTTP::Post
|
69
|
-
when :put then Net::HTTP::Put
|
70
|
-
when :delete then Net::HTTP::Delete
|
71
|
-
end
|
72
|
-
|
73
|
-
req_url = self.build_url(method)
|
74
|
-
|
75
|
-
request = if method == :delete
|
76
|
-
request = request_klass.new([req_url.path, req_url.query].join('?'))
|
77
|
-
else
|
78
|
-
request = request_klass.new(req_url.path)
|
79
|
-
request.set_form_data(params) unless method == :delete
|
80
|
-
request
|
81
|
-
end
|
82
|
-
|
83
|
-
self.class.send(:adapter).log(params, "#{method.to_s.upcase} #{req_url}") do
|
84
|
-
@response = Net::HTTP.new(req_url.host, req_url.port).start { |http| http.request(request) }
|
85
|
-
end
|
86
|
-
parse_response_code(@response)
|
87
|
-
end
|
88
|
-
|
89
|
-
def parse_response_code(response)
|
90
|
-
case response
|
91
|
-
when Net::HTTPSuccess, Net::HTTPRedirection
|
92
|
-
true
|
93
|
-
else
|
94
|
-
false
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
def build_params_from_attributes
|
99
|
-
if self.mutable_post_body_wrapper
|
100
|
-
params = self.mutable_default_parameters
|
101
|
-
@attributes.each do |attribute, value|
|
102
|
-
params.merge!({"#{self.mutable_post_body_wrapper}[#{attribute}]" => value})
|
103
|
-
end
|
104
|
-
# TRP: Append ivar mutable_params to params if set
|
105
|
-
params.merge!(self.mutable_params) if self.mutable_params.is_a?(Hash)
|
106
|
-
|
107
|
-
params
|
108
|
-
else
|
109
|
-
@attributes
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
def build_url(method)
|
114
|
-
url = [self.mutable_host.gsub(%r{/$}, ''), self.mutable_service]
|
115
|
-
url << self.id unless self.new_record?
|
116
|
-
uri = URI.parse "#{url.join('/')}.json"
|
117
|
-
|
118
|
-
if method == :delete
|
119
|
-
uri.query = self.mutable_default_parameters.collect { |key, value| "#{key}=#{value}" }.join('&')
|
120
|
-
end
|
121
|
-
|
122
|
-
uri
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
def self.included(receiver)
|
128
|
-
receiver.class_inheritable_accessor :mutable_service, :mutable_post_body_wrapper
|
129
|
-
receiver.send :attr_accessor, :mutable_params
|
130
|
-
receiver.send(:attr_accessor, :response)
|
131
|
-
|
132
|
-
receiver.extend ClassMethods
|
133
|
-
receiver.send :include, InstanceMethods
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
end
|