sinja 1.1.0.pre4 → 1.2.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -1
  3. data/README.md +96 -29
  4. data/demo-app/.dockerignore +1 -0
  5. data/demo-app/Dockerfile +26 -0
  6. data/demo-app/Gemfile +12 -1
  7. data/demo-app/README.md +39 -24
  8. data/demo-app/Rakefile +36 -0
  9. data/demo-app/app.rb +3 -10
  10. data/demo-app/boot.rb +0 -4
  11. data/demo-app/classes/author.rb +3 -4
  12. data/demo-app/{base.rb → classes/base.rb} +2 -1
  13. data/demo-app/classes/comment.rb +1 -2
  14. data/demo-app/classes/post.rb +17 -10
  15. data/demo-app/classes/tag.rb +7 -3
  16. data/extensions/sequel/Gemfile +4 -0
  17. data/extensions/sequel/LICENSE.txt +21 -0
  18. data/extensions/sequel/README.md +274 -0
  19. data/extensions/sequel/Rakefile +10 -0
  20. data/extensions/sequel/bin/console +14 -0
  21. data/extensions/sequel/bin/setup +8 -0
  22. data/extensions/sequel/lib/sinatra/jsonapi/sequel.rb +7 -0
  23. data/extensions/sequel/lib/sinja-sequel.rb +2 -0
  24. data/extensions/sequel/lib/sinja/sequel.rb +110 -0
  25. data/extensions/sequel/lib/sinja/sequel/core.rb +72 -0
  26. data/extensions/sequel/lib/sinja/sequel/helpers.rb +78 -0
  27. data/extensions/sequel/lib/sinja/sequel/version.rb +6 -0
  28. data/extensions/sequel/sinja-sequel.gemspec +29 -0
  29. data/extensions/sequel/test/test_helper.rb +3 -0
  30. data/lib/sinja.rb +40 -18
  31. data/lib/sinja/config.rb +4 -3
  32. data/lib/sinja/helpers/serializers.rb +2 -1
  33. data/lib/sinja/relationship_routes/has_many.rb +8 -9
  34. data/lib/sinja/relationship_routes/has_one.rb +1 -1
  35. data/lib/sinja/resource.rb +2 -1
  36. data/lib/sinja/resource_routes.rb +2 -2
  37. data/lib/sinja/version.rb +1 -1
  38. data/sinja.gemspec +5 -7
  39. metadata +39 -11
  40. data/.rspec +0 -2
  41. data/lib/sinja/extensions/sequel.rb +0 -53
  42. data/lib/sinja/helpers/sequel.rb +0 -101
data/lib/sinja/config.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'forwardable'
3
3
  require 'set'
4
+
4
5
  require 'sinatra/base'
5
6
 
6
7
  require 'sinja/resource'
@@ -63,15 +64,15 @@ module Sinja
63
64
  :fields=>{}, # passthru to JAS
64
65
  :filter=>{},
65
66
  :page=>{},
66
- :sort=>{}
67
+ :sort=>[]
67
68
  }
68
69
 
69
70
  @error_logger = ->(h) { logger.error('sinja') { h } }
70
71
 
71
72
  @default_roles = {
72
73
  :resource=>RolesConfig.new(%i[show show_many index create update destroy]),
73
- :has_many=>RolesConfig.new(%i[fetch merge subtract clear]),
74
- :has_one=>RolesConfig.new(%i[pluck graft prune])
74
+ :has_many=>RolesConfig.new(%i[fetch clear replace merge subtract]),
75
+ :has_one=>RolesConfig.new(%i[pluck prune graft])
75
76
  }
76
77
 
77
78
  action_proc = proc { |type, hash, action| hash[action] = {
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
+ require 'set'
3
+
2
4
  require 'active_support/inflector'
3
5
  require 'json'
4
6
  require 'jsonapi-serializers'
5
- require 'set'
6
7
 
7
8
  module Sinja
8
9
  module Helpers
@@ -5,6 +5,7 @@ module Sinja
5
5
  def self.registered(app)
6
6
  app.def_action_helper(app, :fetch, %i[roles filter_by sort_by])
7
7
  app.def_action_helper(app, :clear, %i[roles sideload_on])
8
+ app.def_action_helper(app, :replace, %i[roles sideload_on])
8
9
  app.def_action_helper(app, :merge, %i[roles sideload_on])
9
10
  app.def_action_helper(app, :subtract, :roles)
10
11
 
@@ -12,7 +13,7 @@ module Sinja
12
13
  unless relationship_link?
13
14
  allow :get=>:fetch
14
15
  else
15
- allow :get=>:show, :patch=>[:clear, :merge], :post=>:merge, :delete=>:subtract
16
+ allow :get=>:show, :patch=>[:clear, :replace], :post=>:merge, :delete=>:subtract
16
17
  end
17
18
  end
18
19
 
@@ -23,9 +24,9 @@ module Sinja
23
24
  end
24
25
 
25
26
  app.get '', :qparams=>%i[include fields filter sort page], :actions=>:fetch do
26
- filter_sort_page?(:fetch)
27
+ fsp_opts = filter_sort_page?(:fetch)
27
28
  collection, opts = fetch
28
- collection, pagination = filter_sort_page(collection)
29
+ collection, pagination = filter_sort_page(collection, fsp_opts)
29
30
  serialize_models(collection, opts, pagination)
30
31
  end
31
32
 
@@ -33,17 +34,15 @@ module Sinja
33
34
  serialize_linkages?(*clear)
34
35
  end
35
36
 
36
- app.patch '', :actions=>%i[clear merge] do
37
- clear_updated, clear_opts = clear
38
- merge_updated, merge_opts = merge(data)
39
- serialize_linkages?(clear_updated||merge_updated, clear_opts.merge(merge_opts)) # TODO: DWIM?
37
+ app.patch '', :actions=>:replace do
38
+ serialize_linkages?(*replace(data))
40
39
  end
41
40
 
42
- app.post '', :actions=>%i[merge] do
41
+ app.post '', :actions=>:merge do
43
42
  serialize_linkages?(*merge(data))
44
43
  end
45
44
 
46
- app.delete '', :actions=>%i[subtract] do
45
+ app.delete '', :actions=>:subtract do
47
46
  serialize_linkages?(*subtract(data))
48
47
  end
49
48
  end
@@ -4,7 +4,7 @@ module Sinja
4
4
  module HasOne
5
5
  def self.registered(app)
6
6
  app.def_action_helper(app, :pluck, :roles)
7
- app.def_action_helper(app, :prune, :roles)
7
+ app.def_action_helper(app, :prune, %i[roles sideload_on])
8
8
  app.def_action_helper(app, :graft, %i[roles sideload_on])
9
9
 
10
10
  app.head '' do
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
- require 'active_support/inflector'
3
2
  require 'set'
3
+
4
+ require 'active_support/inflector'
4
5
  require 'sinatra/base'
5
6
  require 'sinatra/namespace'
6
7
 
@@ -39,9 +39,9 @@ module Sinja
39
39
  end
40
40
 
41
41
  app.get '', :qparams=>%i[include fields filter sort page], :actions=>:index do
42
- filter_sort_page?(:index)
42
+ fsp_opts = filter_sort_page?(:index)
43
43
  collection, opts = index
44
- collection, pagination = filter_sort_page(collection)
44
+ collection, pagination = filter_sort_page(collection, fsp_opts)
45
45
  serialize_models(collection, opts, pagination)
46
46
  end
47
47
 
data/lib/sinja/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sinja
3
- VERSION = '1.1.0.pre4'
3
+ VERSION = '1.2.0.pre2'
4
4
  end
data/sinja.gemspec CHANGED
@@ -28,14 +28,12 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency 'sinatra-contrib', ">= #{ENV.fetch('sinatra', '1.4.7')}", '< 3'
29
29
 
30
30
  spec.add_development_dependency 'bundler', '~> 1.11'
31
+ spec.add_development_dependency 'jdbc-sqlite3', '~> 3.8' if defined?(JRUBY_VERSION)
31
32
  spec.add_development_dependency 'minitest', '~> 5.9'
32
33
  spec.add_development_dependency 'minitest-hooks', '~> 1.4'
33
34
  #spec.add_development_dependency 'munson', '~> 0.4'
34
- spec.add_development_dependency 'rake', '~> 11.3'
35
- spec.add_development_dependency 'sequel', '~> 4.38'
36
- if defined?(JRUBY_VERSION)
37
- spec.add_development_dependency 'jdbc-sqlite3', '~> 3.8'
38
- else
39
- spec.add_development_dependency 'sqlite3', '~> 1.3'
40
- end
35
+ spec.add_development_dependency 'rake', '~> 12.0'
36
+ spec.add_development_dependency 'sequel', '~> 4.41'
37
+ spec.add_development_dependency 'sinja-sequel', '~> 0.1'
38
+ spec.add_development_dependency 'sqlite3', '~> 1.3' if !defined?(JRUBY_VERSION)
41
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinja
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.pre4
4
+ version: 1.2.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Pastore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-08 00:00:00.000000000 Z
11
+ date: 2016-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -172,28 +172,42 @@ dependencies:
172
172
  requirements:
173
173
  - - "~>"
174
174
  - !ruby/object:Gem::Version
175
- version: '11.3'
175
+ version: '12.0'
176
176
  type: :development
177
177
  prerelease: false
178
178
  version_requirements: !ruby/object:Gem::Requirement
179
179
  requirements:
180
180
  - - "~>"
181
181
  - !ruby/object:Gem::Version
182
- version: '11.3'
182
+ version: '12.0'
183
183
  - !ruby/object:Gem::Dependency
184
184
  name: sequel
185
185
  requirement: !ruby/object:Gem::Requirement
186
186
  requirements:
187
187
  - - "~>"
188
188
  - !ruby/object:Gem::Version
189
- version: '4.38'
189
+ version: '4.41'
190
190
  type: :development
191
191
  prerelease: false
192
192
  version_requirements: !ruby/object:Gem::Requirement
193
193
  requirements:
194
194
  - - "~>"
195
195
  - !ruby/object:Gem::Version
196
- version: '4.38'
196
+ version: '4.41'
197
+ - !ruby/object:Gem::Dependency
198
+ name: sinja-sequel
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - "~>"
202
+ - !ruby/object:Gem::Version
203
+ version: '0.1'
204
+ type: :development
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - "~>"
209
+ - !ruby/object:Gem::Version
210
+ version: '0.1'
197
211
  - !ruby/object:Gem::Dependency
198
212
  name: sqlite3
199
213
  requirement: !ruby/object:Gem::Requirement
@@ -216,7 +230,6 @@ extensions: []
216
230
  extra_rdoc_files: []
217
231
  files:
218
232
  - ".gitignore"
219
- - ".rspec"
220
233
  - ".travis.yml"
221
234
  - Gemfile
222
235
  - LICENSE.txt
@@ -224,24 +237,39 @@ files:
224
237
  - Rakefile
225
238
  - bin/console
226
239
  - bin/setup
240
+ - demo-app/.dockerignore
241
+ - demo-app/Dockerfile
227
242
  - demo-app/Gemfile
228
243
  - demo-app/README.md
244
+ - demo-app/Rakefile
229
245
  - demo-app/app.rb
230
- - demo-app/base.rb
231
246
  - demo-app/boot.rb
232
247
  - demo-app/classes/author.rb
248
+ - demo-app/classes/base.rb
233
249
  - demo-app/classes/comment.rb
234
250
  - demo-app/classes/post.rb
235
251
  - demo-app/classes/tag.rb
236
252
  - demo-app/database.rb
253
+ - extensions/sequel/Gemfile
254
+ - extensions/sequel/LICENSE.txt
255
+ - extensions/sequel/README.md
256
+ - extensions/sequel/Rakefile
257
+ - extensions/sequel/bin/console
258
+ - extensions/sequel/bin/setup
259
+ - extensions/sequel/lib/sinatra/jsonapi/sequel.rb
260
+ - extensions/sequel/lib/sinja-sequel.rb
261
+ - extensions/sequel/lib/sinja/sequel.rb
262
+ - extensions/sequel/lib/sinja/sequel/core.rb
263
+ - extensions/sequel/lib/sinja/sequel/helpers.rb
264
+ - extensions/sequel/lib/sinja/sequel/version.rb
265
+ - extensions/sequel/sinja-sequel.gemspec
266
+ - extensions/sequel/test/test_helper.rb
237
267
  - lib/sinatra/jsonapi.rb
238
268
  - lib/sinja.rb
239
269
  - lib/sinja/config.rb
240
270
  - lib/sinja/errors.rb
241
- - lib/sinja/extensions/sequel.rb
242
271
  - lib/sinja/helpers/nested.rb
243
272
  - lib/sinja/helpers/relationships.rb
244
- - lib/sinja/helpers/sequel.rb
245
273
  - lib/sinja/helpers/serializers.rb
246
274
  - lib/sinja/method_override.rb
247
275
  - lib/sinja/relationship_routes/has_many.rb
@@ -270,7 +298,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
298
  version: 1.3.1
271
299
  requirements: []
272
300
  rubyforge_project:
273
- rubygems_version: 2.5.2
301
+ rubygems_version: 2.6.8
274
302
  signing_key:
275
303
  specification_version: 4
276
304
  summary: RESTful, {json:api}-compliant web services in Sinatra
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'sinja/helpers/sequel'
3
-
4
- module Sinja
5
- module Resource
6
- alias_method :core_has_one, :has_one
7
-
8
- def has_one(rel, &block)
9
- core_has_one(rel) do
10
- pluck do
11
- resource.send(rel)
12
- end
13
-
14
- prune do
15
- resource.send("#{rel}=", nil)
16
- resource.save_changes
17
- end
18
-
19
- graft do |rio|
20
- klass = resource.class.association_reflection(rel).associated_class
21
- resource.send("#{rel}=", klass.with_pk!(rio[:id]))
22
- resource.save_changes(validate: !sideloaded?)
23
- end
24
-
25
- instance_eval(&block) if block
26
- end
27
- end
28
-
29
- alias_method :core_has_many, :has_many
30
-
31
- def has_many(rel, &block)
32
- core_has_many(rel) do
33
- fetch do
34
- resource.send(rel)
35
- end
36
-
37
- clear do
38
- resource.send("remove_all_#{rel}")
39
- end
40
-
41
- merge do |rios|
42
- add_missing(rel, rios)
43
- end
44
-
45
- subtract do |rios|
46
- remove_present(rel, rios)
47
- end
48
-
49
- instance_eval(&block) if block
50
- end
51
- end
52
- end
53
- end
@@ -1,101 +0,0 @@
1
- # frozen_string_literal: true
2
- require 'forwardable'
3
- require 'sequel/model/inflections'
4
-
5
- module Sinja
6
- module Helpers
7
- module Sequel
8
- include ::Sequel::Inflections
9
- extend Forwardable
10
-
11
- def self.config(c)
12
- c.conflict_exceptions << ::Sequel::ConstraintViolation
13
- c.not_found_exceptions << ::Sequel::NoMatchingRow
14
- c.validation_exceptions << ::Sequel::ValidationFailed
15
- c.validation_formatter = ->(e) { e.errors.keys.zip(e.errors.full_messages) }
16
-
17
- c.page_using = {
18
- :number=>1,
19
- :size=>10,
20
- :record_count=>nil
21
- } if ::Sequel::Database::EXTENSIONS.key?(:pagination)
22
- end
23
-
24
- def_delegator ::Sequel::Model, :db, :database
25
- def_delegator :database, :transaction
26
-
27
- def sort(collection, fields)
28
- collection.order(*fields.map { |k, v| ::Sequel.send(v, k) })
29
- end
30
-
31
- def page(collection, opts)
32
- opts = settings._sinja.page_using.merge(opts)
33
- collection = collection.dataset \
34
- unless collection.respond_to?(:paginate)
35
- collection = collection.paginate \
36
- opts[:number].to_i,
37
- opts[:size].to_i,
38
- (opts[:record_count].to_i if opts[:record_count])
39
-
40
- # Attributes common to all pagination links
41
- base = {
42
- :size=>collection.page_size,
43
- :record_count=>collection.pagination_record_count
44
- }
45
- pagination = {
46
- :first=>base.merge(:number=>1),
47
- :self=>base.merge(:number=>collection.current_page),
48
- :last=>base.merge(:number=>collection.page_count)
49
- }
50
- pagination[:next] = base.merge(:number=>collection.next_page) if collection.next_page
51
- pagination[:prev] = base.merge(:number=>collection.prev_page) if collection.prev_page
52
-
53
- return collection, pagination
54
- end if ::Sequel::Database::EXTENSIONS.key?(:pagination)
55
-
56
- define_method :filter, proc(&:where)
57
- define_method :finalize, proc(&:all)
58
-
59
- def validate!
60
- raise ::Sequel::ValidationFailed, resource unless resource.valid?
61
- end
62
-
63
- def next_pk(resource, **opts)
64
- [resource.pk, resource, opts]
65
- end
66
-
67
- # <= association, rios, block
68
- def add_missing(*args, &block)
69
- add_remove(:add, :-, *args, &block)
70
- end
71
-
72
- # <= association, rios, block
73
- def remove_present(*args, &block)
74
- add_remove(:remove, :&, *args, &block)
75
- end
76
-
77
- private
78
-
79
- def add_remove(meth_prefix, operator, association, rios)
80
- meth = "#{meth_prefix}_#{singularize(association)}".to_sym
81
- transaction do
82
- resource.lock!
83
- venn(operator, association, rios) do |subresource|
84
- resource.send(meth, subresource) \
85
- unless block_given? && !yield(subresource)
86
- end
87
- resource.reload
88
- end
89
- end
90
-
91
- def venn(operator, association, rios)
92
- dataset = resource.send("#{association}_dataset")
93
- klass = dataset.association_reflection.associated_class
94
- # does not / will not work with composite primary keys
95
- rios.map { |rio| rio[:id].to_i }
96
- .send(operator, dataset.select_map(:id))
97
- .each { |id| yield klass.with_pk!(id) }
98
- end
99
- end
100
- end
101
- end