rack-scaffold 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62eaf4d70bb8f5ffe5b174b33713b1ebeae39bc5
4
- data.tar.gz: 60452a102b8b505f53dfdc1a6ef2b32a56931ccf
3
+ metadata.gz: 2e321a350a25a6a2fe7440f27ec0e26dbdf6dcb4
4
+ data.tar.gz: d2a63d3b802a9d78efc70f0d2f92feef62dce3dc
5
5
  SHA512:
6
- metadata.gz: 5f9b7caa071e3813f3b0115e68db9ada8c116f57d5283594d3c6811a84faed2781a745ea1866dea66d722d3d9121058cd6f4f78c16c8dcf5009c3990fd51604d
7
- data.tar.gz: 36a22a42bbd975c11cfec13ca44f239774061b8a8a7115eeda608bf96031b84ec74813a7eddc113d72cbac3d1ec125cb1f1e43ee2171c4c578dae97ac351bc09
6
+ metadata.gz: d4bd26aa4a6313a847622a635b5da6d5bf575734092548d75581a8d7806f3a8c872d17495831f9ade59323c424114ba6f1a32a0497cab9f9c03d1dcfe81c5435
7
+ data.tar.gz: d9abfdd3d3bc747130d937a44cbdafcc701f4d127fcddacbe036e0c10e8ba8fefc0ee81f02cc67172a5c548231a16ba7f9ec8e34eb487415beaf449493344575
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-scaffold (0.0.1)
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.2)
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.2)
29
+ sinatra-param (0.1.3)
30
30
  sinatra (~> 1.3)
31
- tilt (1.3.7)
31
+ tilt (1.4.1)
32
32
 
33
33
  PLATFORMS
34
34
  ruby
@@ -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
- {entity.name.downcase => record}.to_json
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}" => resource.paginate(params[:per_page], (params[:page] - 1) * params[:per_page]),
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}" => resource.paginate(params[:limit], params[:offset])
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
- {entity.name.downcase => record}.to_json
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
- {entity.name.downcase => record}.to_json
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?(:delete)
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
- when "Integer 16" then :int2
59
- when "Integer 32" then :int4
60
- when "Integer 64" then :int8
61
- when "Float" then :float4
62
- when "Double" then :float8
63
- when "Decimal" then :float8
64
- when "Date" then :timestamp
65
- when "Boolean" then :boolean
66
- when "Binary" then :bytea
67
- else :varchar
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
- when "Integer 16", "Integer 32", "Integer 64"
101
- validates_integer attribute.name
102
- when "Float", "Double", "Decimal"
103
- validates_numeric attribute.name
104
- when "String"
105
- validates_min_length attribute.minimum_value, attribute.name if attribute.minimum_value
106
- validates_max_length attribute.maximum_value, attribute.name if attribute.maximum_value
107
- end
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
- super(klass)
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, :[], :create!, :update!, :destroy!
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
@@ -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 = Rack::Scaffold::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.1
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-04-23 00:00:00.000000000 Z
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
@@ -1,5 +0,0 @@
1
- module Rack
2
- class Scaffold
3
- VERSION = "0.0.1"
4
- end
5
- end