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