sunstone 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/active_record/connection_adapters/sunstone/column.rb +19 -0
  3. data/lib/active_record/connection_adapters/sunstone/database_statements.rb +40 -0
  4. data/lib/active_record/connection_adapters/sunstone/schema_statements.rb +95 -0
  5. data/lib/active_record/connection_adapters/sunstone/type/date_time.rb +22 -0
  6. data/lib/active_record/connection_adapters/sunstone_adapter.rb +177 -0
  7. data/lib/arel/collectors/sunstone.rb +75 -0
  8. data/lib/arel/visitors/sunstone.rb +769 -0
  9. data/lib/ext/active_record/associations/builder/has_and_belongs_to_many.rb +48 -0
  10. data/lib/ext/active_record/relation.rb +26 -0
  11. data/lib/ext/active_record/statement_cache.rb +24 -0
  12. data/lib/sunstone.rb +37 -347
  13. data/lib/sunstone/connection.rb +337 -0
  14. data/sunstone.gemspec +3 -2
  15. data/test/sunstone/connection_test.rb +319 -0
  16. data/test/sunstone/parser_test.rb +21 -21
  17. metadata +30 -36
  18. data/lib/sunstone/model.rb +0 -23
  19. data/lib/sunstone/model/attributes.rb +0 -99
  20. data/lib/sunstone/model/persistence.rb +0 -168
  21. data/lib/sunstone/schema.rb +0 -38
  22. data/lib/sunstone/type/boolean.rb +0 -19
  23. data/lib/sunstone/type/date_time.rb +0 -20
  24. data/lib/sunstone/type/decimal.rb +0 -19
  25. data/lib/sunstone/type/integer.rb +0 -17
  26. data/lib/sunstone/type/mutable.rb +0 -16
  27. data/lib/sunstone/type/string.rb +0 -18
  28. data/lib/sunstone/type/value.rb +0 -97
  29. data/test/sunstone/model/associations_test.rb +0 -55
  30. data/test/sunstone/model/attributes_test.rb +0 -60
  31. data/test/sunstone/model/persistence_test.rb +0 -173
  32. data/test/sunstone/model_test.rb +0 -11
  33. data/test/sunstone/schema_test.rb +0 -25
  34. data/test/sunstone/type/boolean_test.rb +0 -24
  35. data/test/sunstone/type/date_time_test.rb +0 -31
  36. data/test/sunstone/type/decimal_test.rb +0 -27
  37. data/test/sunstone/type/integer_test.rb +0 -29
  38. data/test/sunstone/type/string_test.rb +0 -54
  39. data/test/sunstone/type/value_test.rb +0 -27
@@ -1,10 +1,10 @@
1
1
  require 'test_helper'
2
2
 
3
- class TestModel < Sunstone::Model
3
+ class TestParserModel < Sunstone::Model
4
4
 
5
- belongs_to :test_model
5
+ belongs_to :test_parser_model
6
6
 
7
- has_many :test_models
7
+ has_many :test_parser_models
8
8
 
9
9
  define_schema do
10
10
  integer :testid
@@ -19,11 +19,11 @@ end
19
19
  class Sunstone::ParserTest < Minitest::Test
20
20
 
21
21
  test '::parse(klass, string)' do
22
- assert_equal true, Sunstone::Parser.parse(TestModel, '{"red": true}').red
22
+ assert_equal true, Sunstone::Parser.parse(TestParserModel, '{"red": true}').red
23
23
  end
24
24
 
25
25
  test '::parse(model_instance, string)' do
26
- model = TestModel.new
26
+ model = TestParserModel.new
27
27
  Sunstone::Parser.parse(model, '{"red": true}')
28
28
  assert_equal true, model.red
29
29
  end
@@ -33,71 +33,71 @@ class Sunstone::ParserTest < Minitest::Test
33
33
  stub_request(:get, "http://testhost.com/test").to_return(:body => '{"red": true}')
34
34
 
35
35
  model = Sunstone.get('/test') do |response|
36
- Sunstone::Parser.parse(TestModel, response)
36
+ Sunstone::Parser.parse(TestParserModel, response)
37
37
  end
38
38
 
39
39
  assert_equal true, model.red
40
40
  end
41
41
 
42
42
  test "parse boolean attributes" do
43
- parser = Sunstone::Parser.new(TestModel)
43
+ parser = Sunstone::Parser.new(TestParserModel)
44
44
  assert_equal true, parser.parse('{"red": true}').red
45
45
 
46
- parser = Sunstone::Parser.new(TestModel)
46
+ parser = Sunstone::Parser.new(TestParserModel)
47
47
  assert_equal false, parser.parse('{"red": false}').red
48
48
  end
49
49
 
50
50
  test "parse date attributes" do
51
- parser = Sunstone::Parser.new(TestModel)
51
+ parser = Sunstone::Parser.new(TestParserModel)
52
52
  assert_equal DateTime.new(2014, 7, 14, 16, 44, 15, '-7'), parser.parse('{"created_at": "2014-07-14T16:44:15-07:00"}').created_at
53
53
  end
54
54
 
55
55
  test "parse decimal attributes" do
56
- parser = Sunstone::Parser.new(TestModel)
56
+ parser = Sunstone::Parser.new(TestParserModel)
57
57
  assert_equal 10.254, parser.parse('{"rate": 10.254}').rate
58
58
  end
59
59
 
60
60
  test "parse integer attributes" do
61
- parser = Sunstone::Parser.new(TestModel)
61
+ parser = Sunstone::Parser.new(TestParserModel)
62
62
  assert_equal 123654, parser.parse('{"testid": 123654}').testid
63
63
  end
64
64
 
65
65
  test "parse string attributes" do
66
- parser = Sunstone::Parser.new(TestModel)
66
+ parser = Sunstone::Parser.new(TestParserModel)
67
67
  assert_equal "my name", parser.parse('{"name": "my name"}').name
68
68
  end
69
69
 
70
70
  test "parse array attribute" do
71
- parser = Sunstone::Parser.new(TestModel)
71
+ parser = Sunstone::Parser.new(TestParserModel)
72
72
  assert_equal ["name 1", "name 2"], parser.parse('{"nicknames": ["name 1", "name 2"]}').nicknames
73
73
  end
74
74
 
75
75
  test "parse skips over unkown key" do
76
76
  assert_nothing_raised do
77
- Sunstone::Parser.parse(TestModel, '{"other_key": "name 2"}')
78
- Sunstone::Parser.parse(TestModel, '{"other_key": ["name 1", "name 2"]}')
77
+ Sunstone::Parser.parse(TestParserModel, '{"other_key": "name 2"}')
78
+ Sunstone::Parser.parse(TestParserModel, '{"other_key": ["name 1", "name 2"]}')
79
79
  end
80
80
  end
81
81
 
82
82
  test "parse belong_to association" do
83
- parser = Sunstone::Parser.new(TestModel)
83
+ parser = Sunstone::Parser.new(TestParserModel)
84
84
  assert_equal({
85
85
  :rate => BigDecimal.new("10.254"),
86
86
  :created_at => DateTime.new(2014, 7, 14, 16, 44, 15, '-7'),
87
87
  :testid => 123654,
88
88
  :name => "my name",
89
89
  :nicknames => ["name 1", "name 2"]
90
- }, parser.parse('{"test_model": {
90
+ }, parser.parse('{"test_parser_model": {
91
91
  "rate": 10.254,
92
92
  "created_at": "2014-07-14T16:44:15-07:00",
93
93
  "testid": 123654,
94
94
  "name": "my name",
95
95
  "nicknames": ["name 1", "name 2"]
96
- }}').test_model.instance_variable_get(:@attributes))
96
+ }}').test_parser_model.instance_variable_get(:@attributes))
97
97
  end
98
98
 
99
99
  test "parse has_many association" do
100
- parser = Sunstone::Parser.new(TestModel)
100
+ parser = Sunstone::Parser.new(TestParserModel)
101
101
  attrs = {
102
102
  :rate => BigDecimal.new("10.254"),
103
103
  :created_at => DateTime.new(2014, 7, 14, 16, 44, 15, '-7'),
@@ -106,7 +106,7 @@ class Sunstone::ParserTest < Minitest::Test
106
106
  :nicknames => ["name 1", "name 2"]
107
107
  }
108
108
 
109
- assert_equal([attrs, attrs], parser.parse('{"test_models": [{
109
+ assert_equal([attrs, attrs], parser.parse('{"test_parser_models": [{
110
110
  "rate": 10.254,
111
111
  "created_at": "2014-07-14T16:44:15-07:00",
112
112
  "testid": 123654,
@@ -118,7 +118,7 @@ class Sunstone::ParserTest < Minitest::Test
118
118
  "testid": 123654,
119
119
  "name": "my name",
120
120
  "nicknames": ["name 1", "name 2"]
121
- }]}').test_models.map{|m| m.instance_variable_get(:@attributes)})
121
+ }]}').test_parser_models.map{|m| m.instance_variable_get(:@attributes)})
122
122
  end
123
123
 
124
124
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sunstone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
11
+ date: 2014-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: arel
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: activesupport
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -221,7 +235,7 @@ dependencies:
221
235
  - !ruby/object:Gem::Version
222
236
  version: '0'
223
237
  - !ruby/object:Gem::Dependency
224
- name: connection_pool
238
+ name: activerecord
225
239
  requirement: !ruby/object:Gem::Requirement
226
240
  requirements:
227
241
  - - ">="
@@ -247,34 +261,24 @@ files:
247
261
  - README.md
248
262
  - Rakefile.rb
249
263
  - TODO.md
264
+ - lib/active_record/connection_adapters/sunstone/column.rb
265
+ - lib/active_record/connection_adapters/sunstone/database_statements.rb
266
+ - lib/active_record/connection_adapters/sunstone/schema_statements.rb
267
+ - lib/active_record/connection_adapters/sunstone/type/date_time.rb
268
+ - lib/active_record/connection_adapters/sunstone_adapter.rb
269
+ - lib/arel/collectors/sunstone.rb
270
+ - lib/arel/visitors/sunstone.rb
271
+ - lib/ext/active_record/associations/builder/has_and_belongs_to_many.rb
272
+ - lib/ext/active_record/relation.rb
273
+ - lib/ext/active_record/statement_cache.rb
250
274
  - lib/sunstone.rb
275
+ - lib/sunstone/connection.rb
251
276
  - lib/sunstone/exception.rb
252
- - lib/sunstone/model.rb
253
277
  - lib/sunstone/model/associations.rb
254
- - lib/sunstone/model/attributes.rb
255
- - lib/sunstone/model/persistence.rb
256
278
  - lib/sunstone/parser.rb
257
- - lib/sunstone/schema.rb
258
- - lib/sunstone/type/boolean.rb
259
- - lib/sunstone/type/date_time.rb
260
- - lib/sunstone/type/decimal.rb
261
- - lib/sunstone/type/integer.rb
262
- - lib/sunstone/type/mutable.rb
263
- - lib/sunstone/type/string.rb
264
- - lib/sunstone/type/value.rb
265
279
  - sunstone.gemspec
266
- - test/sunstone/model/associations_test.rb
267
- - test/sunstone/model/attributes_test.rb
268
- - test/sunstone/model/persistence_test.rb
269
- - test/sunstone/model_test.rb
280
+ - test/sunstone/connection_test.rb
270
281
  - test/sunstone/parser_test.rb
271
- - test/sunstone/schema_test.rb
272
- - test/sunstone/type/boolean_test.rb
273
- - test/sunstone/type/date_time_test.rb
274
- - test/sunstone/type/decimal_test.rb
275
- - test/sunstone/type/integer_test.rb
276
- - test/sunstone/type/string_test.rb
277
- - test/sunstone/type/value_test.rb
278
282
  - test/sunstone_test.rb
279
283
  - test/test_helper.rb
280
284
  homepage: http://sunstonerb.com
@@ -301,18 +305,8 @@ signing_key:
301
305
  specification_version: 4
302
306
  summary: A library for interacting with REST APIs
303
307
  test_files:
304
- - test/sunstone/model/associations_test.rb
305
- - test/sunstone/model/attributes_test.rb
306
- - test/sunstone/model/persistence_test.rb
307
- - test/sunstone/model_test.rb
308
+ - test/sunstone/connection_test.rb
308
309
  - test/sunstone/parser_test.rb
309
- - test/sunstone/schema_test.rb
310
- - test/sunstone/type/boolean_test.rb
311
- - test/sunstone/type/date_time_test.rb
312
- - test/sunstone/type/decimal_test.rb
313
- - test/sunstone/type/integer_test.rb
314
- - test/sunstone/type/string_test.rb
315
- - test/sunstone/type/value_test.rb
316
310
  - test/sunstone_test.rb
317
311
  - test/test_helper.rb
318
312
  has_rdoc:
@@ -1,23 +0,0 @@
1
- require 'sunstone/model/attributes'
2
- require 'sunstone/model/associations'
3
- require 'sunstone/model/persistence'
4
-
5
- module Sunstone
6
- class Model
7
-
8
- extend ActiveModel::Naming
9
- include ActiveModel::Conversion
10
-
11
- include Sunstone::Model::Attributes
12
- include Sunstone::Model::Associations
13
- include Sunstone::Model::Persistence
14
-
15
- def initialize(attrs={})
16
- super
17
- attrs.each do |k, v|
18
- self.send(:"#{k}=", v)
19
- end
20
- end
21
-
22
- end
23
- end
@@ -1,99 +0,0 @@
1
- module Sunstone
2
- class Model
3
-
4
- class SchemaDefiner
5
-
6
- attr_reader :defined_attributes
7
-
8
- def initialize(schema)
9
- @schema = schema
10
- @defined_attributes = []
11
- end
12
-
13
- def attribute(name, type, options = {})
14
- @schema.attribute(name, type, options)
15
- @defined_attributes << name
16
- end
17
-
18
- Sunstone::Type::Value.subclasses.each do |type|
19
- class_eval <<-EOV, __FILE__, __LINE__ + 1
20
- def #{type.name.demodulize.downcase}(name, options = {})
21
- attribute(name, "#{type.name.demodulize.downcase}", options)
22
- end
23
- EOV
24
- end
25
-
26
- end
27
-
28
- module Attributes
29
-
30
- extend ActiveSupport::Concern
31
-
32
- attr_accessor :attributes
33
-
34
- def initialize(*)
35
- @attributes = {}
36
- end
37
-
38
- def schema
39
- self.class.schema
40
- end
41
-
42
- def has?(attribute)
43
- !!@attributes[attribute]
44
- end
45
-
46
- module ClassMethods
47
-
48
- def inherited(subclass)
49
- super
50
- subclass.initialize_schema
51
- end
52
-
53
- def initialize_schema
54
- @schema = Sunstone::Schema.new
55
- attribute(:id, :integer)
56
- end
57
-
58
- def schema
59
- @schema
60
- end
61
-
62
- def define_schema(&block)
63
- definer = SchemaDefiner.new(@schema)
64
- definer.instance_eval(&block)
65
-
66
- definer.defined_attributes.each do |name|
67
- define_attribute_reader(name, @schema[name])
68
- define_attribute_writer(name, @schema[name])
69
- end
70
- end
71
-
72
- def attribute(name, type, options = {})
73
- attribute = @schema.attribute(name, type, options)
74
-
75
- define_attribute_reader(name, attribute)
76
- define_attribute_writer(name, attribute)
77
- end
78
-
79
- def define_attribute_reader(name, type)
80
- class_eval <<-EOV, __FILE__, __LINE__ + 1
81
- def #{name}
82
- @attributes[:#{name}]
83
- end
84
- EOV
85
- end
86
-
87
- def define_attribute_writer(name, type)
88
- class_eval <<-EOV, __FILE__, __LINE__ + 1
89
- def #{name}=(value)
90
- @attributes[:#{name}] = schema[:#{name}].type_cast_from_user(value)
91
- end
92
- EOV
93
- end
94
-
95
- end
96
-
97
- end
98
- end
99
- end
@@ -1,168 +0,0 @@
1
- class Wankel::SaxEncoder
2
-
3
- def value(val)
4
- if val.is_a?(Numeric)
5
- number(val)
6
- elsif val.is_a?(String)
7
- string(val)
8
- elsif val.nil?
9
- null
10
- elsif val == true || val == false
11
- boolean(val)
12
- elsif val.is_a?(Array)
13
- array_open
14
- val.each {|v| value(v) }
15
- array_close
16
- else
17
- puts 'fail'
18
- end
19
- end
20
-
21
- end
22
-
23
- module Sunstone
24
- class Model
25
-
26
- module Persistence
27
-
28
- extend ActiveSupport::Concern
29
-
30
- def initialize(*)
31
- super
32
- @new_record = true
33
- end
34
-
35
- # Returns true if this object hasn't been saved yet -- that is, a record
36
- # for the object doesn't exist in the database yet; otherwise, returns false.
37
- def new_record?
38
- @new_record
39
- end
40
-
41
- # Returns true if this object has been destroyed, otherwise returns false.
42
- def destroyed?
43
- @destroyed
44
- end
45
-
46
- # Returns true if the record is persisted, i.e. it's not a new record and
47
- # it was not destroyed, otherwise returns false.
48
- def persisted?
49
- !(new_record? || destroyed?)
50
- end
51
-
52
- def serialize(options={})
53
- attrs = options[:only] || schema.attributes.keys
54
-
55
- output = StringIO.new
56
- encoder = Wankel::SaxEncoder.new(output)
57
-
58
- encoder.map_open
59
-
60
- attrs.each do |name|
61
- encoder.string name
62
- encoder.value schema[name].type_cast_for_json(self.send(name))
63
- end
64
-
65
- encoder.map_close
66
- encoder.complete
67
- output.string
68
- end
69
-
70
- def serialize_for_create_and_update
71
- attrs = []
72
- schema.attributes.each do |name, type|
73
- attrs << name if name != "id" && !type.readonly?
74
- end
75
-
76
- serialize(:only => attrs)
77
- end
78
-
79
- # Saves the model.
80
- #
81
- # If the model is new a record gets created, otherwise the existing record
82
- # gets updated.
83
- #
84
- # TODO:
85
- # By default, save always run validations. If any of them fail the action
86
- # is cancelled and +save+ returns +false+. However, if you supply
87
- # validate: false, validations are bypassed altogether. See
88
- # ActiveRecord::Validations for more information.
89
- #
90
- # TODO:
91
- # There's a series of callbacks associated with +save+. If any of the
92
- # <tt>before_*</tt> callbacks return +false+ the action is cancelled and
93
- # +save+ returns +false+. See ActiveRecord::Callbacks for further
94
- # details.
95
- #
96
- # Attributes marked as readonly are silently ignored if the record is
97
- # being updated.
98
- def save(*)
99
- create_or_update
100
- rescue Sunstone::RecordInvalid
101
- false
102
- end
103
-
104
- # Saves the model.
105
- #
106
- # If the model is new a record gets created, otherwise the existing record
107
- # gets updated.
108
- #
109
- # TODO:
110
- # With <tt>save!</tt> validations always run. If any of them fail
111
- # ActiveRecord::RecordInvalid gets raised. See ActiveRecord::Validations
112
- # for more information.
113
- #
114
- # TODO:
115
- # There's a series of callbacks associated with <tt>save!</tt>. If any of
116
- # the <tt>before_*</tt> callbacks return +false+ the action is cancelled
117
- # and <tt>save!</tt> raises ActiveRecord::RecordNotSaved. See
118
- # ActiveRecord::Callbacks for further details.
119
- #
120
- # Attributes marked as readonly are silently ignored if the record is
121
- # being updated.
122
- def save!(*)
123
- create_or_update || raise(RecordNotSaved)
124
- end
125
-
126
- private
127
-
128
- def create_or_update
129
- result = new_record? ? _create_record : _update_record
130
- result != false
131
- end
132
-
133
- def _create_record
134
- begin
135
- Sunstone.post("/#{self.class.model_name.route_key}", serialize_for_create_and_update) do |response|
136
- Sunstone::Parser.parse(self, response)
137
- end
138
- @new_record = false
139
- true
140
- rescue Sunstone::Exception::BadRequest => e
141
- Sunstone::Parser.parse(self, e.response)
142
- raise Sunstone::RecordInvalid
143
- end
144
- end
145
-
146
- def _update_record
147
- Sunstone.put("/#{self.class.model_name.route_key}/#{self.to_param}", serialize_for_create_and_update) do |response|
148
- Sunstone::Parser.parse(self, response)
149
- end
150
- end
151
-
152
- module ClassMethods
153
-
154
- def find(id)
155
- Sunstone.get("/#{self.model_name.route_key}/#{id}") do |response|
156
- model = Sunstone::Parser.parse(self, response)
157
- model.instance_variable_set(:@new_record, false)
158
- model
159
- end
160
- end
161
-
162
- end
163
-
164
-
165
- end
166
-
167
- end
168
- end