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.
- checksums.yaml +4 -4
- data/Gemfile +2 -1
- data/README.md +96 -29
- data/demo-app/.dockerignore +1 -0
- data/demo-app/Dockerfile +26 -0
- data/demo-app/Gemfile +12 -1
- data/demo-app/README.md +39 -24
- data/demo-app/Rakefile +36 -0
- data/demo-app/app.rb +3 -10
- data/demo-app/boot.rb +0 -4
- data/demo-app/classes/author.rb +3 -4
- data/demo-app/{base.rb → classes/base.rb} +2 -1
- data/demo-app/classes/comment.rb +1 -2
- data/demo-app/classes/post.rb +17 -10
- data/demo-app/classes/tag.rb +7 -3
- data/extensions/sequel/Gemfile +4 -0
- data/extensions/sequel/LICENSE.txt +21 -0
- data/extensions/sequel/README.md +274 -0
- data/extensions/sequel/Rakefile +10 -0
- data/extensions/sequel/bin/console +14 -0
- data/extensions/sequel/bin/setup +8 -0
- data/extensions/sequel/lib/sinatra/jsonapi/sequel.rb +7 -0
- data/extensions/sequel/lib/sinja-sequel.rb +2 -0
- data/extensions/sequel/lib/sinja/sequel.rb +110 -0
- data/extensions/sequel/lib/sinja/sequel/core.rb +72 -0
- data/extensions/sequel/lib/sinja/sequel/helpers.rb +78 -0
- data/extensions/sequel/lib/sinja/sequel/version.rb +6 -0
- data/extensions/sequel/sinja-sequel.gemspec +29 -0
- data/extensions/sequel/test/test_helper.rb +3 -0
- data/lib/sinja.rb +40 -18
- data/lib/sinja/config.rb +4 -3
- data/lib/sinja/helpers/serializers.rb +2 -1
- data/lib/sinja/relationship_routes/has_many.rb +8 -9
- data/lib/sinja/relationship_routes/has_one.rb +1 -1
- data/lib/sinja/resource.rb +2 -1
- data/lib/sinja/resource_routes.rb +2 -2
- data/lib/sinja/version.rb +1 -1
- data/sinja.gemspec +5 -7
- metadata +39 -11
- data/.rspec +0 -2
- data/lib/sinja/extensions/sequel.rb +0 -53
- 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
|
74
|
-
:has_one=>RolesConfig.new(%i[pluck graft
|
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] = {
|
@@ -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, :
|
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
|
37
|
-
|
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
|
41
|
+
app.post '', :actions=>:merge do
|
43
42
|
serialize_linkages?(*merge(data))
|
44
43
|
end
|
45
44
|
|
46
|
-
app.delete '', :actions
|
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,
|
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
|
data/lib/sinja/resource.rb
CHANGED
@@ -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
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', '~>
|
35
|
-
spec.add_development_dependency 'sequel', '~> 4.
|
36
|
-
|
37
|
-
|
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.
|
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-
|
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: '
|
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: '
|
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.
|
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.
|
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.
|
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,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
|
data/lib/sinja/helpers/sequel.rb
DELETED
@@ -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
|