dao 3.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -106,6 +106,7 @@ READING
106
106
  http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
107
107
  http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
108
108
  http://google-styleguide.googlecode.com/svn/trunk/jsoncstyleguide.xml
109
+ http://pragdave.blogs.pragprog.com/pragdave/2007/03/the_radar_archi.html
109
110
 
110
111
  INSTALL
111
112
  gem 'dao', :path => File.expand_path('..') ### Gemfile
data/a.rb CHANGED
@@ -1,25 +1,80 @@
1
- Api =
2
- Dao.api do
3
- call('/users/:user_id/comments/:comment_id') do
4
- p route
5
- p path
6
- p params
1
+ ##
2
+ #
3
+ require 'dao'
4
+ require 'rubygems'
5
+ gem 'activesupport', '>= 3.0.7'
6
+ require 'active_support'
7
+ require 'active_support/dependencies'
8
+
9
+ ##
10
+ #
11
+ leak =
12
+ lambda do
13
+ Api =
14
+ Dao.api do
15
+ 1000.times do |i|
16
+ call("/foobar-#{ i }") do
17
+ end
18
+ end
19
+ end
20
+
21
+ api = Api.new
22
+
23
+ result = api.call('/foobar-1')
24
+ p result
25
+
26
+ ActiveSupport::Dependencies.unloadable(Api)
27
+ ActiveSupport::Dependencies.remove_unloadable_constants!
7
28
  end
8
- end
9
29
 
10
- api = Api.new
30
+ ##
31
+ #
32
+ n = 10
33
+
34
+ leak.call()
35
+
36
+ GC.start
37
+ leak.call()
38
+ GC.start
39
+
40
+ p :before => Process.size
41
+
42
+
43
+ GC.start
44
+ leak.call()
45
+ GC.start
46
+
47
+ p :after => Process.size
48
+
49
+
50
+
11
51
 
12
- result = api.call('/users/1/comments/2')
13
- puts result.form.input(:user_id)
14
- puts result.form.input(:comment_id)
15
- puts
16
52
 
17
- result = api.call('/users/comments', :user_id => 1, :comment_id => 2)
18
- puts result.form.input(:user_id)
19
- puts result.form.input(:comment_id)
20
- puts
21
53
 
22
- result = api.call('/users/:user_id/comments/:comment_id', :user_id => 1, :comment_id => 2)
23
- puts result.form.input(:user_id)
24
- puts result.form.input(:comment_id)
25
- puts
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ ##
62
+ #
63
+ BEGIN {
64
+
65
+ module Process
66
+ def self.size pid = Process.pid
67
+ stdout = `ps wwwux -p #{ pid }`.split(%r/\n/)
68
+ vsize, rsize = stdout.last.split(%r/\s+/)[4,2]
69
+ end
70
+
71
+ def self.vsize
72
+ size.first
73
+ end
74
+
75
+ def self.rsize
76
+ size.last
77
+ end
78
+ end
79
+
80
+ }
data/dao.gemspec CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "dao"
6
- spec.version = "3.1.0"
6
+ spec.version = "3.1.1"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "dao"
9
9
  spec.description = "description: dao kicks the ass"
@@ -69,6 +69,7 @@ Gem::Specification::new do |spec|
69
69
  "test",
70
70
  "test/dao_test.rb",
71
71
  "test/helper.rb",
72
+ "test/leak.rb",
72
73
  "test/testing.rb",
73
74
  "test/units"]
74
75
 
data/lib/dao.rb CHANGED
@@ -10,7 +10,7 @@
10
10
  # dao libs
11
11
  #
12
12
  module Dao
13
- Version = '3.1.0' unless defined?(Version)
13
+ Version = '3.1.1' unless defined?(Version)
14
14
 
15
15
  def version
16
16
  Dao::Version
@@ -96,10 +96,3 @@
96
96
  unless defined?(D)
97
97
  D = Dao
98
98
  end
99
-
100
- if defined?(Rails.env)
101
- unless Rails.env.production?
102
- unloadable(Dao)
103
- unloadable(D)
104
- end
105
- end
@@ -1,6 +1,6 @@
1
1
  module Dao
2
2
  class Context
3
- Attrs = %w( api route path interface method args status errors params result data form validations )
3
+ Attrs = %w( api route path interface args status errors params result data form validations )
4
4
 
5
5
  Attrs.each{|a| attr_accessor(a)}
6
6
 
@@ -19,8 +19,12 @@ module Dao
19
19
  params = result.params
20
20
  params.update(parsed_params)
21
21
 
22
- method = interface.method.bind(api)
23
- args = [params, result].slice(0, method.arity)
22
+ args =
23
+ if interface.arity < 1
24
+ [params, result]
25
+ else
26
+ [params, result].slice(0, interface.arity)
27
+ end
24
28
 
25
29
  # build the context
26
30
  #
@@ -29,7 +33,6 @@ module Dao
29
33
  context.interface = interface
30
34
  context.route = route
31
35
  context.path = path
32
- context.method = method
33
36
  context.args = args
34
37
  context.status = Status.default
35
38
  context.errors = Errors.new
@@ -56,8 +59,10 @@ module Dao
56
59
  context
57
60
  end
58
61
 
62
+ include InstanceExec
63
+
59
64
  def call
60
- method.call(*args)
65
+ api.instance_exec(*args, &interface)
61
66
  end
62
67
  end
63
68
  end
@@ -3,8 +3,16 @@ module Dao
3
3
  # class methods
4
4
  #
5
5
  class << Api
6
- def interfaces
7
- @interfaces ||= Map.new
6
+ def unload!
7
+ state.clear
8
+ end
9
+
10
+ def state
11
+ @state ||= {
12
+ :interfaces => {},
13
+ :blocks => {},
14
+ :docs => []
15
+ }
8
16
  end
9
17
 
10
18
  def interface(path, &block)
@@ -13,24 +21,22 @@ module Dao
13
21
 
14
22
  route = routes.add(path) if Route.like?(path)
15
23
 
16
- method =
17
- module_eval{
18
- define_method(path + '/interface', &block)
19
- instance_method(path + '/interface')
20
- }
21
-
22
- interface = Interface.new(
24
+ interface = Interface.new({
23
25
  'api' => api,
24
26
  'path' => path,
25
27
  'route' => route,
26
- 'method' => method,
28
+ 'block' => block,
27
29
  'doc' => docs.pop
28
- )
30
+ })
29
31
 
30
32
  interfaces[path] = interface
31
33
  end
32
34
  alias_method('call', 'interface')
33
35
 
36
+ def interfaces
37
+ state[:interfaces]
38
+ end
39
+
34
40
  def description(string)
35
41
  doc(:description => Dao.unindent(string))
36
42
  end
@@ -48,7 +54,7 @@ module Dao
48
54
  end
49
55
 
50
56
  def docs
51
- @docs ||= []
57
+ state[:docs]
52
58
  end
53
59
 
54
60
  def index
@@ -89,6 +95,8 @@ module Dao
89
95
  if Route.like?(path)
90
96
  route = Route.new(path)
91
97
  path = route.path_for(params)
98
+ else
99
+ route = path
92
100
  end
93
101
  end
94
102
 
data/lib/dao/interface.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Dao
2
2
  class Interface
3
- Attrs = %w( api path route method doc )
3
+ Attrs = %w( api path route block doc )
4
4
  Attrs.each{|attr| attr_accessor(attr)}
5
5
 
6
6
  def initialize(options = {})
@@ -12,5 +12,17 @@ module Dao
12
12
  send("#{ key }=", val)
13
13
  end
14
14
  end
15
+
16
+ def arity
17
+ block.arity
18
+ end
19
+
20
+ def call(*args)
21
+ block.call(*args)
22
+ end
23
+
24
+ def to_proc
25
+ block
26
+ end
15
27
  end
16
28
  end
data/lib/dao/rails.rb CHANGED
@@ -1,5 +1,14 @@
1
1
  if defined?(Rails)
2
+
2
3
  module Dao
4
+ ## support unloadable
5
+ #
6
+ def Api.before_remove_const
7
+ unload!
8
+ end
9
+
10
+ ##
11
+ #
3
12
  class Engine < Rails::Engine
4
13
  GEM_DIR = File.expand_path(__FILE__ + '/../../../')
5
14
  ROOT_DIR = File.join(GEM_DIR, 'lib/dao/rails')
@@ -10,10 +19,6 @@ if defined?(Rails)
10
19
 
11
20
  ### config.autoload_paths << APP_DIR
12
21
  ### $LOAD_PATH.push(File.join(Rails.root.to_s, 'app'))
13
- #config.after_initialize do
14
- #unloadable(Dao)
15
- #end
16
-
17
22
 
18
23
  # yes yes, this should probably be somewhere else...
19
24
  #
@@ -24,9 +24,8 @@ protected
24
24
  def respond_with(object, options = {})
25
25
  json = json_for(object)
26
26
 
27
- status = object.status if object.respond_to?(:status)
27
+ status = object.status rescue (options[:status] || 200)
28
28
  status = status.code if status.respond_to?(:code)
29
- status = options[:status] || 200 unless status
30
29
 
31
30
  respond_to do |wants|
32
31
  wants.json{ render :json => json, :status => status }
@@ -50,6 +49,10 @@ protected
50
49
  @path
51
50
  end
52
51
 
52
+ ##
53
+ # you'll likely want to customize this for you app as it makes a few
54
+ # assumptions about how to find and authenticate users
55
+ #
53
56
  def setup_api
54
57
  if white_listed?(path)
55
58
  @api = Api.new
data/test/leak.rb ADDED
@@ -0,0 +1,86 @@
1
+ ##
2
+ #
3
+ require 'rubygems'
4
+ #gem 'activesupport', '>= 3.0.7'
5
+ #require 'active_support'
6
+ #require 'active_support/dependencies'
7
+
8
+ require 'rails/all'
9
+ require 'dao'
10
+
11
+ ##
12
+ #
13
+ gc =
14
+ lambda do
15
+ 10.times{ GC.start }
16
+ end
17
+
18
+ leak =
19
+ lambda do
20
+ Api =
21
+ Dao.api do
22
+ 1000.times do |i|
23
+ call("/foobar-#{ i }") do
24
+ end
25
+ end
26
+ end
27
+
28
+ api = Api.new
29
+
30
+ result = api.call('/foobar-1')
31
+ result.route || abort(result.inspect)
32
+
33
+ ActiveSupport::Dependencies.unloadable(Api)
34
+ ActiveSupport::Dependencies.remove_unloadable_constants!
35
+ gc.call()
36
+ end
37
+
38
+ ##
39
+ #
40
+ n = 10
41
+
42
+ paths = 0
43
+ ObjectSpace.each_object(Dao::Path){ paths += 1}
44
+ p 'paths' => paths
45
+
46
+ leak.call()
47
+ before = Process.size
48
+
49
+ paths = 0
50
+ ObjectSpace.each_object(Dao::Path){ paths += 1}
51
+ p 'paths' => paths
52
+
53
+ leak.call()
54
+ after = Process.size
55
+
56
+ paths = 0
57
+ ObjectSpace.each_object(Dao::Path){ paths += 1}
58
+ p 'paths' => paths
59
+
60
+ delta = [after.first - before.first, after.last - before.last]
61
+
62
+ p :before => before
63
+ p :after => after
64
+ p :delta => delta
65
+
66
+
67
+ ##
68
+ #
69
+ BEGIN {
70
+
71
+ module Process
72
+ def self.size pid = Process.pid
73
+ stdout = `ps wwwux -p #{ pid }`.split(%r/\n/)
74
+ vsize, rsize = stdout.last.split(%r/\s+/)[4,2].map{|i| i.to_i}
75
+ end
76
+
77
+ def self.vsize
78
+ size.first.to_i
79
+ end
80
+
81
+ def self.rsize
82
+ size.last.to_i
83
+ end
84
+ end
85
+
86
+ }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dao
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 1
9
- - 0
10
- version: 3.1.0
9
+ - 1
10
+ version: 3.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ara T. Howard
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-17 00:00:00 -06:00
18
+ date: 2011-06-07 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -78,6 +78,7 @@ files:
78
78
  - lib/dao/validations/common.rb
79
79
  - test/dao_test.rb
80
80
  - test/helper.rb
81
+ - test/leak.rb
81
82
  - test/testing.rb
82
83
  has_rdoc: true
83
84
  homepage: https://github.com/ahoward/dao