rack-scaffold 0.0.1 → 0.0.2
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -4
- data/lib/rack/scaffold.rb +24 -8
- data/lib/rack/scaffold/adapters.rb +9 -1
- data/lib/rack/scaffold/adapters/active_record.rb +9 -1
- data/lib/rack/scaffold/adapters/core_data.rb +32 -22
- data/lib/rack/scaffold/adapters/sequel.rb +12 -3
- data/rack-scaffold-0.0.1.gem +0 -0
- data/rack-scaffold.gemspec +1 -2
- metadata +3 -3
- data/lib/rack/scaffold/version.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e321a350a25a6a2fe7440f27ec0e26dbdf6dcb4
|
4
|
+
data.tar.gz: d2a63d3b802a9d78efc70f0d2f92feef62dce3dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4bd26aa4a6313a847622a635b5da6d5bf575734092548d75581a8d7806f3a8c872d17495831f9ade59323c424114ba6f1a32a0497cab9f9c03d1dcfe81c5435
|
7
|
+
data.tar.gz: d9abfdd3d3bc747130d937a44cbdafcc701f4d127fcddacbe036e0c10e8ba8fefc0ee81f02cc67172a5c548231a16ba7f9ec8e34eb487415beaf449493344575
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rack-scaffold (0.0.
|
4
|
+
rack-scaffold (0.0.2)
|
5
5
|
activesupport (>= 3.0)
|
6
6
|
rack (~> 1.4)
|
7
7
|
rack-contrib (~> 1.1)
|
@@ -15,7 +15,7 @@ GEM
|
|
15
15
|
i18n (= 0.6.1)
|
16
16
|
multi_json (~> 1.0)
|
17
17
|
i18n (0.6.1)
|
18
|
-
multi_json (1.7.
|
18
|
+
multi_json (1.7.3)
|
19
19
|
rack (1.5.2)
|
20
20
|
rack-contrib (1.1.0)
|
21
21
|
rack (>= 0.9.1)
|
@@ -26,9 +26,9 @@ GEM
|
|
26
26
|
rack (~> 1.5, >= 1.5.2)
|
27
27
|
rack-protection (~> 1.4)
|
28
28
|
tilt (~> 1.3, >= 1.3.4)
|
29
|
-
sinatra-param (0.1.
|
29
|
+
sinatra-param (0.1.3)
|
30
30
|
sinatra (~> 1.3)
|
31
|
-
tilt (1.
|
31
|
+
tilt (1.4.1)
|
32
32
|
|
33
33
|
PLATFORMS
|
34
34
|
ruby
|
data/lib/rack/scaffold.rb
CHANGED
@@ -3,7 +3,6 @@ require 'rack/contrib'
|
|
3
3
|
require 'sinatra/base'
|
4
4
|
require 'sinatra/param'
|
5
5
|
|
6
|
-
require 'rack/scaffold/version'
|
7
6
|
require 'rack/scaffold/adapters'
|
8
7
|
|
9
8
|
module Rack
|
@@ -26,6 +25,15 @@ module Rack
|
|
26
25
|
end
|
27
26
|
|
28
27
|
disable :raise_errors, :show_exceptions
|
28
|
+
|
29
|
+
def last_modified_time(resource, resources)
|
30
|
+
update_timestamp_field = resource.update_timestamp_field.to_sym
|
31
|
+
most_recently_updated = resources.class.include?(Enumerable) ? resources.max_by(&update_timestamp_field) : resources
|
32
|
+
|
33
|
+
timestamp = request.env['HTTP_IF_MODIFIED_SINCE']
|
34
|
+
timestamp = most_recently_updated.send(update_timestamp_field) if most_recently_updated
|
35
|
+
timestamp
|
36
|
+
end
|
29
37
|
end
|
30
38
|
|
31
39
|
@actions = (options[:only] || ACTIONS) - (options[:except] || [])
|
@@ -33,13 +41,13 @@ module Rack
|
|
33
41
|
@adapter = Rack::Scaffold.adapters.detect{|adapter| adapter === options[:model]}
|
34
42
|
raise "No suitable adapters found for #{options[:model]} in #{Rack::Scaffold.adapters}" unless @adapter
|
35
43
|
|
36
|
-
resources = Array(@adapter.resources(options[:model]))
|
44
|
+
resources = Array(@adapter.resources(options[:model], options))
|
37
45
|
resources.each do |resource|
|
38
46
|
@app.instance_eval do
|
39
47
|
post "/#{resource.plural}/?" do
|
40
48
|
if record = resource.create!(params)
|
41
49
|
status 201
|
42
|
-
{
|
50
|
+
{"#{resource.singular}" => record}.to_json
|
43
51
|
else
|
44
52
|
status 406
|
45
53
|
{errors: record.errors}.to_json
|
@@ -53,8 +61,11 @@ module Rack
|
|
53
61
|
param :page, Integer, default: 1, min: 1
|
54
62
|
param :per_page, Integer, default: 100, in: (1..100)
|
55
63
|
|
64
|
+
resources = resource.paginate(params[:per_page], (params[:page] - 1) * params[:per_page])
|
65
|
+
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
66
|
+
|
56
67
|
{
|
57
|
-
"#{resource.plural}" =>
|
68
|
+
"#{resource.plural}" => resources,
|
58
69
|
page: params[:page],
|
59
70
|
total: resource.count
|
60
71
|
}.to_json
|
@@ -62,16 +73,21 @@ module Rack
|
|
62
73
|
param :limit, Integer, default: 100, in: (1..100)
|
63
74
|
param :offset, Integer, default: 0, min: 0
|
64
75
|
|
76
|
+
resources = resource.paginate(params[:limit], params[:offset])
|
77
|
+
last_modified(last_modified_time(resource, resources)) if resource.timestamps?
|
78
|
+
|
65
79
|
{
|
66
|
-
"#{resource.plural}" =>
|
80
|
+
"#{resource.plural}" => resources
|
67
81
|
}.to_json
|
68
82
|
end
|
69
83
|
end
|
70
84
|
|
71
85
|
get "/#{resource.plural}/:id/?" do
|
72
86
|
record = resource[params[:id]] or halt 404
|
73
|
-
|
87
|
+
last_modified(last_modified_time(resource, record)) if resource.timestamps?
|
88
|
+
{"#{resource.singular}" => record}.to_json
|
74
89
|
end
|
90
|
+
|
75
91
|
end if @actions.include?(:read)
|
76
92
|
|
77
93
|
@app.instance_eval do
|
@@ -79,7 +95,7 @@ module Rack
|
|
79
95
|
record = resource[params[:id]] or halt 404
|
80
96
|
if record.update!(params)
|
81
97
|
status 200
|
82
|
-
{
|
98
|
+
{"#{resource.singular}" => record}.to_json
|
83
99
|
else
|
84
100
|
status 406
|
85
101
|
{errors: record.errors}.to_json
|
@@ -97,7 +113,7 @@ module Rack
|
|
97
113
|
{errors: record.errors}.to_json
|
98
114
|
end
|
99
115
|
end
|
100
|
-
end if @actions.include?(:
|
116
|
+
end if @actions.include?(:destroy)
|
101
117
|
|
102
118
|
# @app.instance_eval do
|
103
119
|
# entity.relationships.each do |relationship|
|
@@ -20,7 +20,7 @@ module Rack
|
|
20
20
|
raise NotImplementedError
|
21
21
|
end
|
22
22
|
|
23
|
-
def resources(model)
|
23
|
+
def resources(model, options = {})
|
24
24
|
raise NotImplementedError
|
25
25
|
end
|
26
26
|
end
|
@@ -68,6 +68,14 @@ module Rack
|
|
68
68
|
def destroy!
|
69
69
|
raise NotImplementedError
|
70
70
|
end
|
71
|
+
|
72
|
+
def timestamps?
|
73
|
+
raise NotImplementedError
|
74
|
+
end
|
75
|
+
|
76
|
+
def update_timestamp_field
|
77
|
+
raise NotImplementedError
|
78
|
+
end
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
@@ -12,9 +12,13 @@ module Rack::Scaffold::Adapters
|
|
12
12
|
::ActiveRecord::Base === model
|
13
13
|
end
|
14
14
|
|
15
|
-
def resources(model)
|
15
|
+
def resources(model, options = {})
|
16
16
|
model
|
17
17
|
end
|
18
|
+
|
19
|
+
def timestamps?
|
20
|
+
record_timestamps?
|
21
|
+
end
|
18
22
|
end
|
19
23
|
|
20
24
|
def singular
|
@@ -32,5 +36,9 @@ module Rack::Scaffold::Adapters
|
|
32
36
|
def [](id)
|
33
37
|
self.find(id)
|
34
38
|
end
|
39
|
+
|
40
|
+
def update_timestamp_field
|
41
|
+
self.attribute_names.include?("updated_at") ? "updated_at" : "updated_on"
|
42
|
+
end
|
35
43
|
end
|
36
44
|
end
|
@@ -10,13 +10,13 @@ module Rack::Scaffold::Adapters
|
|
10
10
|
!! ::CoreData::DataModel.new(model) rescue false
|
11
11
|
end
|
12
12
|
|
13
|
-
def resources(xcdatamodel)
|
13
|
+
def resources(xcdatamodel, options = {})
|
14
14
|
model = ::CoreData::DataModel.new(xcdatamodel)
|
15
|
-
model.entities.collect{|entity| new(entity)}
|
15
|
+
model.entities.collect{|entity| new(entity, options)}
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
-
def initialize(entity)
|
19
|
+
def initialize(entity, options = {})
|
20
20
|
klass = Class.new(::Sequel::Model)
|
21
21
|
klass.dataset = entity.name.downcase.pluralize.to_sym
|
22
22
|
|
@@ -28,6 +28,15 @@ module Rack::Scaffold::Adapters
|
|
28
28
|
plugin :schema
|
29
29
|
plugin :validation_helpers
|
30
30
|
|
31
|
+
if options[:timestamps]
|
32
|
+
if options[:timestamps].instance_of? Hash
|
33
|
+
plugin :timestamps, options[:timestamps]
|
34
|
+
else
|
35
|
+
plugin :timestamps
|
36
|
+
end
|
37
|
+
# plugin :timestamps, create: :createdAt, update: :updatedAt
|
38
|
+
end
|
39
|
+
|
31
40
|
def url
|
32
41
|
"/#{self.class.table_name}/#{self[primary_key]}"
|
33
42
|
end
|
@@ -55,16 +64,16 @@ module Rack::Scaffold::Adapters
|
|
55
64
|
}
|
56
65
|
|
57
66
|
type = case attribute.type
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
67
|
+
when "Integer 16" then :int2
|
68
|
+
when "Integer 32" then :int4
|
69
|
+
when "Integer 64" then :int8
|
70
|
+
when "Float" then :float4
|
71
|
+
when "Double" then :float8
|
72
|
+
when "Decimal" then :float8
|
73
|
+
when "Date" then :timestamp
|
74
|
+
when "Boolean" then :boolean
|
75
|
+
when "Binary" then :bytea
|
76
|
+
else :varchar
|
68
77
|
end
|
69
78
|
|
70
79
|
column attribute.name.to_sym, type, options
|
@@ -97,18 +106,19 @@ module Rack::Scaffold::Adapters
|
|
97
106
|
klass.send :define_method, :validate do
|
98
107
|
entity.attributes.each do |attribute|
|
99
108
|
case attribute.type
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
109
|
+
when "Integer 16", "Integer 32", "Integer 64"
|
110
|
+
validates_integer attribute.name
|
111
|
+
when "Float", "Double", "Decimal"
|
112
|
+
validates_numeric attribute.name
|
113
|
+
when "String"
|
114
|
+
validates_min_length attribute.minimum_value, attribute.name if attribute.minimum_value
|
115
|
+
validates_max_length attribute.maximum_value, attribute.name if attribute.maximum_value
|
116
|
+
end
|
108
117
|
end
|
109
118
|
end
|
110
119
|
|
111
|
-
|
120
|
+
|
121
|
+
super(CoreData.const_set(entity.name, klass))
|
112
122
|
end
|
113
123
|
end
|
114
124
|
end
|
@@ -5,20 +5,24 @@ module Rack::Scaffold::Adapters
|
|
5
5
|
class Sequel < Base
|
6
6
|
extend Forwardable
|
7
7
|
|
8
|
-
def_delegators :@klass, :count, :all, :find, :[], :
|
8
|
+
def_delegators :@klass, :count, :all, :find, :[], :update_timestamp_field
|
9
|
+
def_delegator :@klass, :create, :create!
|
10
|
+
def_delegator :@klass, :update, :update!
|
11
|
+
def_delegator :@klass, :destroy, :destroy!
|
9
12
|
|
10
13
|
class << self
|
11
14
|
def ===(model)
|
12
15
|
::Sequel::Model === model
|
13
16
|
end
|
14
17
|
|
15
|
-
def resources(model)
|
18
|
+
def resources(model, options = {})
|
16
19
|
model
|
17
20
|
end
|
21
|
+
|
18
22
|
end
|
19
23
|
|
20
24
|
def singular
|
21
|
-
@klass.name
|
25
|
+
@klass.name.demodulize.downcase
|
22
26
|
end
|
23
27
|
|
24
28
|
def plural
|
@@ -28,5 +32,10 @@ module Rack::Scaffold::Adapters
|
|
28
32
|
def paginate(limit, offset)
|
29
33
|
@klass.limit(limit, offset)
|
30
34
|
end
|
35
|
+
|
36
|
+
def timestamps?
|
37
|
+
defined?(::Sequel::Plugins::Timestamps) and @klass.plugins.include?(::Sequel::Plugins::Timestamps)
|
38
|
+
end
|
39
|
+
|
31
40
|
end
|
32
41
|
end
|
Binary file
|
data/rack-scaffold.gemspec
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
|
-
require "rack/scaffold/version"
|
4
3
|
|
5
4
|
Gem::Specification.new do |s|
|
6
5
|
s.name = "rack-scaffold"
|
@@ -8,7 +7,7 @@ Gem::Specification.new do |s|
|
|
8
7
|
s.email = "m@mattt.me"
|
9
8
|
s.homepage = "http://mattt.me"
|
10
9
|
s.license = "MIT"
|
11
|
-
s.version =
|
10
|
+
s.version = "0.0.2"
|
12
11
|
s.platform = Gem::Platform::RUBY
|
13
12
|
s.summary = "Rack::Scaffold"
|
14
13
|
s.description = "Automatically generate RESTful CRUD services"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-scaffold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mattt Thompson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -106,9 +106,9 @@ files:
|
|
106
106
|
- ./lib/rack/scaffold/adapters/core_data.rb
|
107
107
|
- ./lib/rack/scaffold/adapters/sequel.rb
|
108
108
|
- ./lib/rack/scaffold/adapters.rb
|
109
|
-
- ./lib/rack/scaffold/version.rb
|
110
109
|
- ./lib/rack/scaffold.rb
|
111
110
|
- ./LICENSE
|
111
|
+
- ./rack-scaffold-0.0.1.gem
|
112
112
|
- ./rack-scaffold.gemspec
|
113
113
|
- ./Rakefile
|
114
114
|
- ./README.md
|