activerecord-simpledb-adapter 0.2.1 → 0.3.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/Gemfile +1 -0
- data/Gemfile.lock +40 -38
- data/activerecord-simpledb-adapter.gemspec +23 -11
- data/lib/active_record/connection_adapters/simpledb_adapter.rb +8 -466
- data/lib/active_record/connection_adapters/simpledb_adapter/adapter.rb +258 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/base.rb +65 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/column.rb +62 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/finder_methods.rb +20 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/misc/aws_overrides.rb +53 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/misc/simpledb_logger.rb +15 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/table_definition.rb +32 -0
- data/lib/active_record/connection_adapters/simpledb_adapter/validations.rb +50 -0
- data/spec/active_record/batch_spec.rb +67 -0
- data/spec/spec_helper.rb +8 -1
- metadata +67 -43
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,34 +2,35 @@ GEM
|
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
4
|
abstract (1.0.0)
|
5
|
-
actionmailer (3.0.
|
6
|
-
actionpack (= 3.0.
|
7
|
-
mail (~> 2.2.
|
8
|
-
actionpack (3.0.
|
9
|
-
activemodel (= 3.0.
|
10
|
-
activesupport (= 3.0.
|
5
|
+
actionmailer (3.0.7)
|
6
|
+
actionpack (= 3.0.7)
|
7
|
+
mail (~> 2.2.15)
|
8
|
+
actionpack (3.0.7)
|
9
|
+
activemodel (= 3.0.7)
|
10
|
+
activesupport (= 3.0.7)
|
11
11
|
builder (~> 2.1.2)
|
12
12
|
erubis (~> 2.6.6)
|
13
|
-
i18n (~> 0.
|
13
|
+
i18n (~> 0.5.0)
|
14
14
|
rack (~> 1.2.1)
|
15
|
-
rack-mount (~> 0.6.
|
16
|
-
rack-test (~> 0.5.
|
15
|
+
rack-mount (~> 0.6.14)
|
16
|
+
rack-test (~> 0.5.7)
|
17
17
|
tzinfo (~> 0.3.23)
|
18
|
-
activemodel (3.0.
|
19
|
-
activesupport (= 3.0.
|
18
|
+
activemodel (3.0.7)
|
19
|
+
activesupport (= 3.0.7)
|
20
20
|
builder (~> 2.1.2)
|
21
|
-
i18n (~> 0.
|
22
|
-
activerecord (3.0.
|
23
|
-
activemodel (= 3.0.
|
24
|
-
activesupport (= 3.0.
|
21
|
+
i18n (~> 0.5.0)
|
22
|
+
activerecord (3.0.7)
|
23
|
+
activemodel (= 3.0.7)
|
24
|
+
activesupport (= 3.0.7)
|
25
25
|
arel (~> 2.0.2)
|
26
26
|
tzinfo (~> 0.3.23)
|
27
|
-
activeresource (3.0.
|
28
|
-
activemodel (= 3.0.
|
29
|
-
activesupport (= 3.0.
|
30
|
-
activesupport (3.0.
|
31
|
-
arel (2.0.
|
32
|
-
|
27
|
+
activeresource (3.0.7)
|
28
|
+
activemodel (= 3.0.7)
|
29
|
+
activesupport (= 3.0.7)
|
30
|
+
activesupport (3.0.7)
|
31
|
+
arel (2.0.9)
|
32
|
+
awesome_print (0.3.2)
|
33
|
+
aws (2.4.5)
|
33
34
|
activesupport
|
34
35
|
http_connection
|
35
36
|
uuidtools
|
@@ -42,35 +43,35 @@ GEM
|
|
42
43
|
rspec (>= 2.0.0.beta.14)
|
43
44
|
sc-core-ext (>= 1.2.1)
|
44
45
|
git (1.2.5)
|
45
|
-
http_connection (1.4.
|
46
|
+
http_connection (1.4.1)
|
46
47
|
i18n (0.5.0)
|
47
48
|
jeweler (1.5.2)
|
48
49
|
bundler (~> 1.0.0)
|
49
50
|
git (>= 1.2.5)
|
50
51
|
rake
|
51
|
-
mail (2.2.
|
52
|
+
mail (2.2.17)
|
52
53
|
activesupport (>= 2.3.6)
|
53
54
|
i18n (>= 0.4.0)
|
54
55
|
mime-types (~> 1.16)
|
55
56
|
treetop (~> 1.4.8)
|
56
57
|
mime-types (1.16)
|
57
58
|
polyglot (0.3.1)
|
58
|
-
rack (1.2.
|
59
|
-
rack-mount (0.6.
|
59
|
+
rack (1.2.2)
|
60
|
+
rack-mount (0.6.14)
|
60
61
|
rack (>= 1.0.0)
|
61
62
|
rack-test (0.5.7)
|
62
63
|
rack (>= 1.0)
|
63
|
-
rails (3.0.
|
64
|
-
actionmailer (= 3.0.
|
65
|
-
actionpack (= 3.0.
|
66
|
-
activerecord (= 3.0.
|
67
|
-
activeresource (= 3.0.
|
68
|
-
activesupport (= 3.0.
|
64
|
+
rails (3.0.7)
|
65
|
+
actionmailer (= 3.0.7)
|
66
|
+
actionpack (= 3.0.7)
|
67
|
+
activerecord (= 3.0.7)
|
68
|
+
activeresource (= 3.0.7)
|
69
|
+
activesupport (= 3.0.7)
|
69
70
|
bundler (~> 1.0)
|
70
|
-
railties (= 3.0.
|
71
|
-
railties (3.0.
|
72
|
-
actionpack (= 3.0.
|
73
|
-
activesupport (= 3.0.
|
71
|
+
railties (= 3.0.7)
|
72
|
+
railties (3.0.7)
|
73
|
+
actionpack (= 3.0.7)
|
74
|
+
activesupport (= 3.0.7)
|
74
75
|
rake (>= 0.8.7)
|
75
76
|
thor (~> 0.14.4)
|
76
77
|
rake (0.8.7)
|
@@ -88,9 +89,9 @@ GEM
|
|
88
89
|
thor (0.14.6)
|
89
90
|
treetop (1.4.9)
|
90
91
|
polyglot (>= 0.3.1)
|
91
|
-
tzinfo (0.3.
|
92
|
-
uuidtools (2.1.
|
93
|
-
xml-simple (1.0.
|
92
|
+
tzinfo (0.3.26)
|
93
|
+
uuidtools (2.1.2)
|
94
|
+
xml-simple (1.0.15)
|
94
95
|
|
95
96
|
PLATFORMS
|
96
97
|
ruby
|
@@ -98,6 +99,7 @@ PLATFORMS
|
|
98
99
|
DEPENDENCIES
|
99
100
|
activerecord
|
100
101
|
activesupport
|
102
|
+
awesome_print
|
101
103
|
aws
|
102
104
|
bundler (~> 1.0.0)
|
103
105
|
genspec (= 0.2.0.prerails3.2)
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{activerecord-simpledb-adapter}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ilia Ablamonov", "Alex Gorkunov", "Cloud Castle Inc."]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-04-21}
|
13
13
|
s.email = %q{ilia@flamefork.ru}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE.txt",
|
@@ -22,6 +22,14 @@ Gem::Specification.new do |s|
|
|
22
22
|
"README.md",
|
23
23
|
"activerecord-simpledb-adapter.gemspec",
|
24
24
|
"lib/active_record/connection_adapters/simpledb_adapter.rb",
|
25
|
+
"lib/active_record/connection_adapters/simpledb_adapter/adapter.rb",
|
26
|
+
"lib/active_record/connection_adapters/simpledb_adapter/base.rb",
|
27
|
+
"lib/active_record/connection_adapters/simpledb_adapter/column.rb",
|
28
|
+
"lib/active_record/connection_adapters/simpledb_adapter/finder_methods.rb",
|
29
|
+
"lib/active_record/connection_adapters/simpledb_adapter/misc/aws_overrides.rb",
|
30
|
+
"lib/active_record/connection_adapters/simpledb_adapter/misc/simpledb_logger.rb",
|
31
|
+
"lib/active_record/connection_adapters/simpledb_adapter/table_definition.rb",
|
32
|
+
"lib/active_record/connection_adapters/simpledb_adapter/validations.rb",
|
25
33
|
"lib/activerecord-simpledb-adapter.rb",
|
26
34
|
"lib/arel/visitors/simpledb.rb",
|
27
35
|
"lib/generators/active_record/model/model_generator.rb",
|
@@ -34,6 +42,7 @@ Gem::Specification.new do |s|
|
|
34
42
|
s.rubygems_version = %q{1.3.7}
|
35
43
|
s.summary = %q{ActiveRecord SimpleDB adapter}
|
36
44
|
s.test_files = [
|
45
|
+
"spec/active_record/batch_spec.rb",
|
37
46
|
"spec/active_record/connection_adapters/simpledb_adapter_spec.rb",
|
38
47
|
"spec/active_record/core_actions_spec.rb",
|
39
48
|
"spec/active_record/defaults_spec.rb",
|
@@ -52,6 +61,7 @@ Gem::Specification.new do |s|
|
|
52
61
|
s.specification_version = 3
|
53
62
|
|
54
63
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
|
+
s.add_development_dependency(%q<awesome_print>, [">= 0"])
|
55
65
|
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
56
66
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
67
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
@@ -63,11 +73,12 @@ Gem::Specification.new do |s|
|
|
63
73
|
s.add_development_dependency(%q<thor>, [">= 0"])
|
64
74
|
s.add_development_dependency(%q<rails>, [">= 0"])
|
65
75
|
s.add_runtime_dependency(%q<aws>, ["~> 2.3.0"])
|
66
|
-
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.
|
67
|
-
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.
|
76
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.7"])
|
77
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.7"])
|
68
78
|
s.add_runtime_dependency(%q<uuidtools>, ["~> 2.1.1"])
|
69
|
-
s.add_runtime_dependency(%q<rails>, ["~> 3.0.
|
79
|
+
s.add_runtime_dependency(%q<rails>, ["~> 3.0.7"])
|
70
80
|
else
|
81
|
+
s.add_dependency(%q<awesome_print>, [">= 0"])
|
71
82
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
72
83
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
73
84
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
@@ -79,12 +90,13 @@ Gem::Specification.new do |s|
|
|
79
90
|
s.add_dependency(%q<thor>, [">= 0"])
|
80
91
|
s.add_dependency(%q<rails>, [">= 0"])
|
81
92
|
s.add_dependency(%q<aws>, ["~> 2.3.0"])
|
82
|
-
s.add_dependency(%q<activerecord>, ["~> 3.0.
|
83
|
-
s.add_dependency(%q<activesupport>, ["~> 3.0.
|
93
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
|
94
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.7"])
|
84
95
|
s.add_dependency(%q<uuidtools>, ["~> 2.1.1"])
|
85
|
-
s.add_dependency(%q<rails>, ["~> 3.0.
|
96
|
+
s.add_dependency(%q<rails>, ["~> 3.0.7"])
|
86
97
|
end
|
87
98
|
else
|
99
|
+
s.add_dependency(%q<awesome_print>, [">= 0"])
|
88
100
|
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
89
101
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
90
102
|
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
@@ -96,10 +108,10 @@ Gem::Specification.new do |s|
|
|
96
108
|
s.add_dependency(%q<thor>, [">= 0"])
|
97
109
|
s.add_dependency(%q<rails>, [">= 0"])
|
98
110
|
s.add_dependency(%q<aws>, ["~> 2.3.0"])
|
99
|
-
s.add_dependency(%q<activerecord>, ["~> 3.0.
|
100
|
-
s.add_dependency(%q<activesupport>, ["~> 3.0.
|
111
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.7"])
|
112
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.7"])
|
101
113
|
s.add_dependency(%q<uuidtools>, ["~> 2.1.1"])
|
102
|
-
s.add_dependency(%q<rails>, ["~> 3.0.
|
114
|
+
s.add_dependency(%q<rails>, ["~> 3.0.7"])
|
103
115
|
end
|
104
116
|
end
|
105
117
|
|
@@ -3,469 +3,11 @@ require 'active_support/core_ext/kernel/requires'
|
|
3
3
|
require 'active_support/core_ext/hash'
|
4
4
|
require 'uuidtools'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def delete_attributes(domain_name, item_name, attributes = nil, expected_attributes = {})
|
16
|
-
params = params_with_attributes(domain_name, item_name, attributes, false, expected_attributes)
|
17
|
-
link = generate_request("DeleteAttributes", params)
|
18
|
-
request_info( link, QSdbSimpleParser.new )
|
19
|
-
rescue Exception
|
20
|
-
on_exception
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
def pack_expected_attributes(attributes) #:nodoc:
|
25
|
-
{}.tap do |result|
|
26
|
-
idx = 0
|
27
|
-
attributes.each do |attribute, value|
|
28
|
-
v = value.is_a?(Array) ? value.first : value
|
29
|
-
result["Expected.#{idx}.Name"] = attribute.to_s
|
30
|
-
result["Expected.#{idx}.Value"] = ruby_to_sdb(v)
|
31
|
-
idx += 1
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def pack_attributes(attributes = {}, replace = false, key_prefix = "")
|
37
|
-
{}.tap do |result|
|
38
|
-
idx = 0
|
39
|
-
if attributes
|
40
|
-
attributes.each do |attribute, value|
|
41
|
-
v = value.is_a?(Array) ? value.first : value
|
42
|
-
result["#{key_prefix}Attribute.#{idx}.Replace"] = 'true' if replace
|
43
|
-
result["#{key_prefix}Attribute.#{idx}.Name"] = attribute
|
44
|
-
result["#{key_prefix}Attribute.#{idx}.Value"] = ruby_to_sdb(v)
|
45
|
-
idx += 1
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def params_with_attributes(domain_name, item_name, attributes, replace, expected_attrubutes)
|
52
|
-
{}.tap do |p|
|
53
|
-
p['DomainName'] = domain_name
|
54
|
-
p['ItemName'] = item_name
|
55
|
-
p.merge!(pack_attributes(attributes, replace)).merge!(pack_expected_attributes(expected_attrubutes))
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
module ActiveRecord
|
61
|
-
|
62
|
-
class SimpleDBLogger
|
63
|
-
def initialize(logger)
|
64
|
-
@logger = logger
|
65
|
-
end
|
66
|
-
|
67
|
-
def info *args
|
68
|
-
#skip noisy info messages from aws interface
|
69
|
-
end
|
70
|
-
|
71
|
-
def method_missing m, *args
|
72
|
-
@logger.send(m, args)
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
class Base
|
78
|
-
def self.simpledb_connection(config) # :nodoc:
|
79
|
-
require 'aws'
|
80
|
-
|
81
|
-
config = config.symbolize_keys
|
82
|
-
|
83
|
-
ConnectionAdapters::SimpleDBAdapter.new nil, logger,
|
84
|
-
config[:access_key_id],
|
85
|
-
config[:secret_access_key],
|
86
|
-
config[:domain_name],
|
87
|
-
{
|
88
|
-
:server => config[:host],
|
89
|
-
:port => config[:port],
|
90
|
-
:protocol => config[:protocol],
|
91
|
-
:connection_mode => :per_thread,
|
92
|
-
:logger => SimpleDBLogger.new(logger)
|
93
|
-
},
|
94
|
-
config
|
95
|
-
end
|
96
|
-
|
97
|
-
DEFAULT_COLLECTION_COLUMN_NAME = "collection".freeze
|
98
|
-
|
99
|
-
def self.columns_definition options = {}
|
100
|
-
table_definition = ConnectionAdapters::SimpleDbTableDifinition.new(options[:collection_column_name] || DEFAULT_COLLECTION_COLUMN_NAME)
|
101
|
-
table_definition.primary_key(Base.get_primary_key(table_name.to_s.singularize))
|
102
|
-
|
103
|
-
alias_method_chain :initialize, :defaults
|
104
|
-
|
105
|
-
yield table_definition if block_given?
|
106
|
-
|
107
|
-
ConnectionAdapters::SimpleDBAdapter.set_collection_columns table_name, table_definition
|
108
|
-
end
|
109
|
-
|
110
|
-
def initialize_with_defaults(attrs = nil)
|
111
|
-
initialize_without_defaults(attrs) do
|
112
|
-
safe_attribute_names = []
|
113
|
-
if attrs
|
114
|
-
stringified_attrs = attrs.stringify_keys
|
115
|
-
safe_attrs = sanitize_for_mass_assignment(stringified_attrs)
|
116
|
-
safe_attribute_names = safe_attrs.keys.map { |x| x.to_s }
|
117
|
-
end
|
118
|
-
|
119
|
-
ActiveRecord::Base.connection.columns_definition(self.class.table_name).columns_with_defaults.each do |column|
|
120
|
-
if !safe_attribute_names.any? { |attr_name| attr_name =~ /^#{column.name}($|\()/ }
|
121
|
-
value = if column.default.is_a? Proc
|
122
|
-
column.default.call(self)
|
123
|
-
else
|
124
|
-
column.default
|
125
|
-
end
|
126
|
-
__send__("#{column.name}=", value)
|
127
|
-
changed_attributes.delete(column.name)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
yield(self) if block_given?
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
module Validations
|
137
|
-
|
138
|
-
class UniquenessValidator < ActiveModel::EachValidator
|
139
|
-
|
140
|
-
def validate_each(record, attribute, value)
|
141
|
-
finder_class = find_finder_class_for(record)
|
142
|
-
table = finder_class.unscoped
|
143
|
-
|
144
|
-
table_name = record.class.quoted_table_name
|
145
|
-
|
146
|
-
if value && record.class.serialized_attributes.key?(attribute.to_s)
|
147
|
-
value = YAML.dump value
|
148
|
-
end
|
149
|
-
|
150
|
-
sql, params = mount_sql_and_params(finder_class, table_name, attribute, value)
|
151
|
-
|
152
|
-
relation = table.where(sql, *params)
|
153
|
-
|
154
|
-
Array.wrap(options[:scope]).each do |scope_item|
|
155
|
-
scope_value = record.send(scope_item)
|
156
|
-
relation = relation.where(scope_item => scope_value)
|
157
|
-
end
|
158
|
-
|
159
|
-
if record.persisted?
|
160
|
-
# TODO : This should be in Arel
|
161
|
-
relation = relation.where("#{record.class.primary_key} != ?", record.send(:id))
|
162
|
-
end
|
163
|
-
|
164
|
-
if relation.exists?
|
165
|
-
record.errors.add(attribute, :taken, options.except(:case_sensitive, :scope).merge(:value => value))
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
protected
|
170
|
-
def mount_sql_and_params(klass, table_name, attribute, value) #:nodoc:
|
171
|
-
column = klass.columns_hash[attribute.to_s]
|
172
|
-
|
173
|
-
sql_attribute = "#{klass.connection.quote_column_name(column.db_column_name)}"
|
174
|
-
sql = "#{sql_attribute} = ?"
|
175
|
-
if value.nil?
|
176
|
-
[sql, [value]]
|
177
|
-
elsif (options[:case_sensitive] || !column.text?)
|
178
|
-
[sql, [value]]
|
179
|
-
else
|
180
|
-
[sql, [value.downcase]]
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
end
|
186
|
-
|
187
|
-
module ConnectionAdapters
|
188
|
-
|
189
|
-
class SimpleDbTableDifinition < TableDefinition
|
190
|
-
|
191
|
-
attr_reader :collection_column_name
|
192
|
-
|
193
|
-
def initialize collection_column_name
|
194
|
-
super nil
|
195
|
-
@collection_column_name = collection_column_name
|
196
|
-
end
|
197
|
-
|
198
|
-
def xml_column_fallback(*args)
|
199
|
-
raise ConfigurationError, "Not supported"
|
200
|
-
end
|
201
|
-
|
202
|
-
def [](name)
|
203
|
-
@columns.find {|column| column.db_column_name == name.to_s}
|
204
|
-
end
|
205
|
-
|
206
|
-
def column(name, type, options = {})
|
207
|
-
raise ConfigurationError, %Q(column '#{collection_column_name}' reserved, please change column name) if name.to_s == collection_column_name
|
208
|
-
@columns << SimpleDBColumn.new(name.to_s, type.to_sym, options[:limit], options[:precision], options[:to], options[:default])
|
209
|
-
self
|
210
|
-
end
|
211
|
-
|
212
|
-
def columns_with_defaults
|
213
|
-
@columns_with_defaults ||= @columns.select { |column| column.default.present? }
|
214
|
-
end
|
215
|
-
|
216
|
-
end
|
217
|
-
|
218
|
-
class SimpleDBColumn < Column
|
219
|
-
|
220
|
-
DEFAULT_NUMBER_LIMIT = 4
|
221
|
-
DEFAULT_FLOAT_PRECISION = 4
|
222
|
-
|
223
|
-
def initialize(name, type, limit = nil, pricision = nil, to = nil, default = nil)
|
224
|
-
super name, nil, type, true
|
225
|
-
@limit = limit if limit.present?
|
226
|
-
@precision = precision if precision.present?
|
227
|
-
@default = default
|
228
|
-
@to = to
|
229
|
-
end
|
230
|
-
|
231
|
-
def quote_number value
|
232
|
-
case sql_type
|
233
|
-
when :float then
|
234
|
-
sprintf("%.#{number_precision}f", number_shift + value.to_f)
|
235
|
-
else
|
236
|
-
(number_shift + value.to_i).to_s
|
237
|
-
end
|
238
|
-
end
|
239
|
-
|
240
|
-
def unquote_number value
|
241
|
-
return nil if value.nil?
|
242
|
-
|
243
|
-
case sql_type
|
244
|
-
when :integer then
|
245
|
-
value.to_i - number_shift
|
246
|
-
when :float then
|
247
|
-
precision_part = 10 ** number_precision
|
248
|
-
((value.to_f - number_shift) * precision_part).round / precision_part.to_f
|
249
|
-
else
|
250
|
-
value
|
251
|
-
end
|
252
|
-
end
|
253
|
-
|
254
|
-
def db_column_name
|
255
|
-
@to || name
|
256
|
-
end
|
257
|
-
|
258
|
-
private
|
259
|
-
def number_shift
|
260
|
-
5 * 10 ** (limit || DEFAULT_NUMBER_LIMIT)
|
261
|
-
end
|
262
|
-
|
263
|
-
def number_precision
|
264
|
-
@precision || DEFAULT_FLOAT_PRECISION
|
265
|
-
end
|
266
|
-
|
267
|
-
def simplified_type(field_type)
|
268
|
-
t = field_type.to_s
|
269
|
-
if t == "primary_key"
|
270
|
-
:string
|
271
|
-
else
|
272
|
-
super(t)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
class SimpleDBAdapter < AbstractAdapter
|
278
|
-
|
279
|
-
@@collections = {}
|
280
|
-
@@ccn = {}
|
281
|
-
|
282
|
-
def self.set_collection_columns table_name, columns_definition
|
283
|
-
@@collections[table_name] = columns_definition
|
284
|
-
@@ccn[table_name] = columns_definition.collection_column_name
|
285
|
-
end
|
286
|
-
|
287
|
-
def columns_definition table_name
|
288
|
-
@@collections[table_name]
|
289
|
-
end
|
290
|
-
|
291
|
-
def collection_column_name table_name
|
292
|
-
@@ccn[table_name]
|
293
|
-
end
|
294
|
-
|
295
|
-
ADAPTER_NAME = 'SimpleDB'.freeze
|
296
|
-
|
297
|
-
def adapter_name
|
298
|
-
ADAPTER_NAME
|
299
|
-
end
|
300
|
-
|
301
|
-
NIL_REPRESENTATION = "Aws::Nil".freeze
|
302
|
-
|
303
|
-
def nil_representation
|
304
|
-
NIL_REPRESENTATION
|
305
|
-
end
|
306
|
-
|
307
|
-
|
308
|
-
def supports_count_distinct?; false; end
|
309
|
-
|
310
|
-
#========= QUOTING =====================
|
311
|
-
|
312
|
-
#dirty hack for removing all (') from value for hash table attrubutes
|
313
|
-
def hash_value_quote(value, column = nil)
|
314
|
-
return nil if value.nil?
|
315
|
-
quote(value, column).gsub /^'*|'*$/, ''
|
316
|
-
end
|
317
|
-
|
318
|
-
def quote(value, column = nil)
|
319
|
-
if value.present? && column.present? && column.number?
|
320
|
-
"'#{column.quote_number value}'"
|
321
|
-
elsif value.nil?
|
322
|
-
"'#{nil_representation}'"
|
323
|
-
else
|
324
|
-
super
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
def quote_column_name(column_name)
|
329
|
-
"`#{column_name}`"
|
330
|
-
end
|
331
|
-
|
332
|
-
def quote_table_name(table_name)
|
333
|
-
table_name
|
334
|
-
end
|
335
|
-
#=======================================
|
336
|
-
|
337
|
-
attr_reader :domain_name
|
338
|
-
|
339
|
-
def initialize(connection, logger, aws_key, aws_secret, domain_name, connection_parameters, config)
|
340
|
-
super(connection, logger)
|
341
|
-
@config = config
|
342
|
-
@domain_name = domain_name
|
343
|
-
@connection_parameters = [
|
344
|
-
aws_key,
|
345
|
-
aws_secret,
|
346
|
-
connection_parameters.merge(:nil_representation => nil_representation)
|
347
|
-
]
|
348
|
-
connect
|
349
|
-
end
|
350
|
-
|
351
|
-
def connect
|
352
|
-
@connection = Aws::SdbInterface.new *@connection_parameters
|
353
|
-
end
|
354
|
-
|
355
|
-
def tables
|
356
|
-
@@collections.keys
|
357
|
-
end
|
358
|
-
|
359
|
-
def columns table_name, name = nil
|
360
|
-
@@collections[table_name].columns
|
361
|
-
end
|
362
|
-
|
363
|
-
def primary_key _
|
364
|
-
'id'
|
365
|
-
end
|
366
|
-
|
367
|
-
def execute sql, name = nil, skip_logging = false
|
368
|
-
log sql.inspect, "SimpleDB" do
|
369
|
-
case sql[:action]
|
370
|
-
when :insert
|
371
|
-
item_name = get_id sql[:attrs]
|
372
|
-
item_name = sql[:attrs][:id] = generate_id unless item_name
|
373
|
-
@connection.put_attributes domain_name, item_name, sql[:attrs], true
|
374
|
-
@last_insert_id = item_name
|
375
|
-
when :update
|
376
|
-
item_name = get_id sql[:wheres], true
|
377
|
-
@connection.put_attributes domain_name, item_name, sql[:attrs], true, sql[:wheres]
|
378
|
-
when :delete
|
379
|
-
item_name = get_id sql[:wheres], true
|
380
|
-
@connection.delete_attributes domain_name, item_name, nil, sql[:wheres]
|
381
|
-
else
|
382
|
-
raise "Unsupported action: #{sql[:action].inspect}"
|
383
|
-
end
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
def insert_sql sql, name = nil, pk = nil, id_value = nil, sequence_name = nil
|
388
|
-
super || @last_insert_id
|
389
|
-
end
|
390
|
-
alias :create :insert_sql
|
391
|
-
|
392
|
-
def select sql, name = nil
|
393
|
-
log sql, "SimpleDB" do
|
394
|
-
result = []
|
395
|
-
response = @connection.select(sql, nil, true)
|
396
|
-
collection_name = get_collection_column_and_name(sql)
|
397
|
-
columns = columns_definition(collection_name)
|
398
|
-
|
399
|
-
response[:items].each do |item|
|
400
|
-
item.each do |id, attrs|
|
401
|
-
ritem = {}
|
402
|
-
ritem['id'] = id unless id == 'Domain' && attrs['Count'] # unless count(*) result
|
403
|
-
attrs.each {|k, vs|
|
404
|
-
column = columns[k]
|
405
|
-
if column.present?
|
406
|
-
ritem[column.name] = column.unquote_number(vs.first)
|
407
|
-
else
|
408
|
-
ritem[k] = vs.first
|
409
|
-
end
|
410
|
-
}
|
411
|
-
result << ritem
|
412
|
-
end
|
413
|
-
end
|
414
|
-
result
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
# Executes the update statement and returns the number of rows affected.
|
419
|
-
def update_sql(sql, name = nil)
|
420
|
-
begin
|
421
|
-
execute(sql, name)
|
422
|
-
1
|
423
|
-
rescue Aws::AwsError => ex
|
424
|
-
#if not conflict state raise
|
425
|
-
raise if ex.http_code != '409'
|
426
|
-
0
|
427
|
-
end
|
428
|
-
end
|
429
|
-
|
430
|
-
# Executes the delete statement and returns the number of rows affected.
|
431
|
-
def delete_sql(sql, name = nil)
|
432
|
-
update_sql(sql, name)
|
433
|
-
end
|
434
|
-
|
435
|
-
def create_domain domain_name
|
436
|
-
@connection.create_domain domain_name
|
437
|
-
end
|
438
|
-
|
439
|
-
def delete_domain domain_name
|
440
|
-
@connection.delete_domain domain_name
|
441
|
-
end
|
442
|
-
|
443
|
-
def list_domains
|
444
|
-
@connection.list_domains[:domains]
|
445
|
-
end
|
446
|
-
|
447
|
-
private
|
448
|
-
|
449
|
-
def generate_id
|
450
|
-
UUIDTools::UUID.timestamp_create().to_s
|
451
|
-
end
|
452
|
-
|
453
|
-
def get_id hash, delete_id = false
|
454
|
-
if delete_id
|
455
|
-
hash.delete(:id) || hash.delete('id')
|
456
|
-
else
|
457
|
-
hash[:id] || hash['id']
|
458
|
-
end
|
459
|
-
end
|
460
|
-
|
461
|
-
def get_collection_column_and_name sql
|
462
|
-
if sql.match /`?(#{@@ccn.values.join("|")})`?\s*=\s*'(.*?)'/
|
463
|
-
$2
|
464
|
-
else
|
465
|
-
raise PreparedStatementInvalid, "collection column '#{@@ccn.values.join(" or ")}' not found in the WHERE section in query"
|
466
|
-
end
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
end
|
471
|
-
end
|
6
|
+
require 'active_record/connection_adapters/simpledb_adapter/misc/aws_overrides'
|
7
|
+
require 'active_record/connection_adapters/simpledb_adapter/misc/simpledb_logger'
|
8
|
+
require 'active_record/connection_adapters/simpledb_adapter/finder_methods'
|
9
|
+
require 'active_record/connection_adapters/simpledb_adapter/base'
|
10
|
+
require 'active_record/connection_adapters/simpledb_adapter/validations'
|
11
|
+
require 'active_record/connection_adapters/simpledb_adapter/table_definition'
|
12
|
+
require 'active_record/connection_adapters/simpledb_adapter/column'
|
13
|
+
require 'active_record/connection_adapters/simpledb_adapter/adapter'
|