dao 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -2,29 +2,109 @@ NAME
2
2
  dao
3
3
 
4
4
  SYNOPSIS
5
- a library for structuring rails applications using the 'data access object' pattern
5
+ a sa-weet-ass library for structuring rails applications using the 'data
6
+ access object' design pattern.
6
7
 
7
8
  DESCRITPION
8
- stay tuned...
9
-
10
- ISSUES ADRESSED
11
- . testability
12
- . documentability
13
- . being able to reason about code
14
- . reasoning about caching
15
- . avoiding duplicating logic in html/api
16
- . avoid N+1 in view
17
- . avoid design issues with REST (delete(1,2,3))
18
- . nested attributes trivally
19
- . lack of domain (current_user)
20
- . easily optimize queries later
21
- . magic
9
+ applications that are written on dao look like this in ruby
10
+
11
+ result = api.call('/posts/new', params)
12
+
13
+ and like this in javascript
14
+
15
+ result = api.call('/posts/new', params)
16
+
17
+ in command-line applications they look like this
18
+
19
+ result = api.call('/posts/new', params)
20
+
21
+ and in tests this syntax is used
22
+
23
+ result = api.call('/posts/new', params)
24
+
25
+ when a developer wants to understand the interface of a dao application she
26
+ does this
27
+
28
+ vi app/api.rb
29
+
30
+ when a developer of a dao application wants to play with a dao application
31
+ interactively she does
32
+
33
+ (rails console)
34
+
35
+ > api = Api.new
36
+ > result = api.call('/posts/new', params)
37
+
38
+ when a remote client wants to understand the api of a dao application she
39
+ does
40
+
41
+ curl --silent http://dao.app.com/api | less
42
+
43
+
44
+
45
+ this kind of brutally consistent interface is made possible by structuring
46
+ access to data around the finest data structure of all time - the hash. in
47
+ the case of dao the hash is a well structured and slightly clever hash, but
48
+ a simple hash interface is the basis of every bit of goodness dao has to
49
+ offer.
50
+
51
+ in dao, application developers do not bring models into controllers and,
52
+ especially not into views. instead, a unified interface to application
53
+ logic and data is used everywhere: in tests, in controllers, from the
54
+ command-line, and also from javascript.
55
+
56
+ this speration of concerns brings with it many, many desirable qualities:
57
+
58
+ - total seperation of concerns between the front and back end of a web
59
+ application. when developers are using dao changes to the data model
60
+ have zero effect on controllers and views.
61
+
62
+ - issues related to having models in controllers and views such as
63
+ difficulty reasoning about caching and n+1 queries in views killing the
64
+ db simply disappear.
65
+
66
+ - bad programming practices like using quasi-global variables
67
+ (current_user) or decorating models with view specific attributes
68
+ (password_verification) are no longer needed.
69
+
70
+ - developers are able to reason over the abilities of an application by
71
+ reading only a few source files.
72
+
73
+ - databases can be swapped, mixed, or alternate storage/caching mechanisms
74
+ added at any time without affecting the application's controllers or
75
+ views.
76
+
77
+ - transition from form based views to semi-ajax ones to fully-ajax ones is
78
+ direct.
79
+
80
+ - forms and interfaces that involve dozens of models are as easy to deal
81
+ with as simple ones.
82
+
83
+ - code can be optimized at the interface
84
+
85
+
86
+ wikipedia has this to say about dao in general
87
+
88
+ "
89
+
90
+ In computer software, a data access object (DAO) is an object that
91
+ provides an abstract interface to some type of database or persistence
92
+ mechanism, providing some specific operations without exposing details
93
+ of the database. It provides a mapping from application calls to the
94
+ persistence layer. This isolation separates the concerns of what data
95
+ accesses the application needs, in terms of domain-specific objects and
96
+ data types (the public interface of the DAO), and how these needs can be
97
+ satisfied with a specific DBMS, database schema, etc. (the
98
+ implementation of the DAO).
99
+
100
+ "
101
+ - http://en.wikipedia.org/wiki/Data_access_object
22
102
 
23
103
  READING
24
- http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
25
104
  http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/dao.html
26
105
  http://www.codefutures.com/data-access-object/
27
106
  http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html
107
+ http://www.paperplanes.de/2010/5/7/activerecord_callbacks_ruined_my_life.html
28
108
 
29
109
  INSTALL
30
110
  gem 'dao', :path => File.expand_path('..') ### Gemfile
@@ -32,4 +112,3 @@ INSTALL
32
112
  vim -o app/api.rb app/controllers/api_controller.rb
33
113
  curl --silent http://0.0.0.0:3000/api
34
114
  curl --silent http://0.0.0.0:3000/api/ping
35
-
data/Rakefile CHANGED
@@ -83,14 +83,16 @@ task :gemspec do
83
83
  end
84
84
 
85
85
  lib = This.lib
86
- object = This.object
86
+ namespace = This.namespace
87
87
  version = This.version
88
88
  files = shiteless[Dir::glob("**/**")]
89
89
  executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
90
90
  has_rdoc = true #File.exist?('doc')
91
91
  test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
92
- summary = object.respond_to?(:summary) ? object.summary : "summary: #{ lib } kicks the ass"
93
- description = object.respond_to?(:description) ? object.description : "description: #{ lib } kicks the ass"
92
+
93
+ summary = namespace.respond_to?(:summary) ? namespace.summary : "summary: #{ lib } kicks the ass"
94
+ description = namespace.respond_to?(:description) ? namespace.description : "description: #{ lib } kicks the ass"
95
+ dependencies = namespace.respond_to?(:dependencies) ? namespace.dependencies : []
94
96
 
95
97
  if This.extensions.nil?
96
98
  This.extensions = []
@@ -103,44 +105,48 @@ task :gemspec do
103
105
 
104
106
  template =
105
107
  if test(?e, 'gemspec.erb')
106
- Template{ IO.read('gemspec.erb') }
108
+ IO.read('gemspec.erb')
107
109
  else
108
- Template {
109
- <<-__
110
- ## #{ lib }.gemspec
111
- #
112
-
113
- Gem::Specification::new do |spec|
114
- spec.name = #{ lib.inspect }
115
- spec.version = #{ version.inspect }
116
- spec.platform = Gem::Platform::RUBY
117
- spec.summary = #{ lib.inspect }
118
- spec.description = #{ description.inspect }
119
-
120
- spec.files = #{ files.inspect }
121
- spec.executables = #{ executables.inspect }
122
-
123
- spec.require_path = "lib"
124
-
125
- spec.has_rdoc = #{ has_rdoc.inspect }
126
- spec.test_files = #{ test_files.inspect }
127
-
128
- # spec.add_dependency 'lib', '>= version'
129
- spec.add_dependency 'map'
130
- spec.add_dependency 'tagz'
131
- spec.add_dependency 'yajl-ruby'
132
-
133
- spec.extensions.push(*#{ extensions.inspect })
134
-
135
- spec.rubyforge_project = #{ This.rubyforge_project.inspect }
136
- spec.author = #{ This.author.inspect }
137
- spec.email = #{ This.email.inspect }
138
- spec.homepage = #{ This.homepage.inspect }
139
- end
140
- __
141
- }
110
+ <<-__
111
+ ## <%= lib %>.gemspec
112
+ #
113
+
114
+ Gem::Specification::new do |spec|
115
+ spec.name = <%= lib.inspect %>
116
+ spec.version = <%= version.inspect %>
117
+ spec.platform = Gem::Platform::RUBY
118
+ spec.summary = <%= lib.inspect %>
119
+ spec.description = <%= description.inspect %>
120
+
121
+ spec.files = <%= files.inspect %>
122
+ spec.executables = <%= executables.inspect %>
123
+
124
+ spec.require_path = "lib"
125
+
126
+ spec.has_rdoc = <%= has_rdoc.inspect %>
127
+
128
+ <% if defined?(test_files) %>
129
+ spec.test_files = <%= test_files.inspect %>
130
+ <% end %>
131
+
132
+ <% dependencies.each do |dependency|
133
+ lib, spec = dependency
134
+ %>
135
+ spec.add_dependency(*<%= spec.inspect %>)
136
+ <% end %>
137
+
138
+ spec.extensions.push(*<%= extensions.inspect %>)
139
+
140
+ spec.rubyforge_project = <%= This.rubyforge_project.inspect %>
141
+ spec.author = <%= This.author.inspect %>
142
+ spec.email = <%= This.email.inspect %>
143
+ spec.homepage = <%= This.homepage.inspect %>
144
+ end
145
+ __
142
146
  end
143
147
 
148
+ template = Template{ template }
149
+
144
150
  Fu.mkdir_p(This.pkgdir)
145
151
  This.gemspec = File.join(This.dir, "#{ This.lib }.gemspec") #File.join(This.pkgdir, "gemspec.rb")
146
152
  open("#{ This.gemspec }", "w"){|fd| fd.puts(template)}
@@ -231,6 +237,7 @@ BEGIN {
231
237
  require 'erb'
232
238
  require 'fileutils'
233
239
  require 'rbconfig'
240
+ require 'yaml'
234
241
 
235
242
  # fu shortcut
236
243
  #
@@ -244,28 +251,70 @@ BEGIN {
244
251
  This.dir = File.dirname(This.file)
245
252
  This.pkgdir = File.join(This.dir, 'pkg')
246
253
 
254
+ # use pkg.yml iff present
255
+ #
256
+ pkg_config_yml = File.join(This.dir, 'pkg/config.yml')
257
+ if test(?e, pkg_config_yml)
258
+ pkg_config = YAML::load(ERB.new(IO.read(pkg_config_yml)).result)
259
+
260
+ if pkg_config.is_a?(Hash)
261
+ ENV['LIB'] ||= pkg_config['lib']
262
+ ENV['AUTOREQUIRE'] ||= pkg_config['autorequire']
263
+ ENV['VERSION'] ||= pkg_config['version']
264
+ ENV['NAME'] ||= pkg_config['name']
265
+ ENV['NAMESPACE'] ||= pkg_config['namespace']
266
+ end
267
+ end
268
+
247
269
  # grok lib
248
270
  #
249
271
  lib = ENV['LIB']
250
272
  unless lib
251
- lib = File.basename(Dir.pwd).sub(/[-].*$/, '')
273
+ lib = File.basename(This.dir).sub(/[-].*$/, '')
252
274
  end
253
275
  This.lib = lib
254
276
 
277
+ # grok autorequire
278
+ #
279
+ autorequire = ENV['AUTOREQUIRE']
280
+ unless autorequire
281
+ autorequire = File.join(This.dir, 'lib', This.lib)
282
+ end
283
+ This.autorequire = autorequire
284
+
285
+ # load the package
286
+ #
287
+ require This.autorequire
288
+
289
+ # grok name
290
+ #
291
+ name = ENV['NAME']
292
+ unless name
293
+ name = This.lib.capitalize
294
+ end
295
+ This.name = name
296
+
297
+ # grok namespace
298
+ #
299
+ namespace = ENV['NAMESPACE']
300
+ unless namespace
301
+ namespace = This.name
302
+ end
303
+ This.namespace = eval(namespace)
304
+
255
305
  # grok version
256
306
  #
257
307
  version = ENV['VERSION']
258
308
  unless version
259
- require "./lib/#{ This.lib }"
260
- This.name = lib.capitalize
261
- This.object = eval(This.name)
262
- version = This.object.send(:version)
309
+ version = This.namespace.send(:version)
263
310
  end
264
311
  This.version = version
265
312
 
266
313
  # we need to know the name of the lib an it's version
267
314
  #
268
315
  abort('no lib') unless This.lib
316
+ abort('no name') unless This.name
317
+ abort('no namespace') unless This.namespace
269
318
  abort('no version') unless This.version
270
319
 
271
320
  # discover full path to this ruby executable
data/dao.gemspec CHANGED
@@ -2,24 +2,28 @@
2
2
  #
3
3
 
4
4
  Gem::Specification::new do |spec|
5
- spec.name = "dao"
6
- spec.version = "2.0.0"
5
+ spec.name = "dao"
6
+ spec.version = "2.1.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "dao"
9
9
  spec.description = "description: dao kicks the ass"
10
10
 
11
- spec.files = ["dao.gemspec", "db", "db/dao.yml", "lib", "lib/dao", "lib/dao/active_record.rb", "lib/dao/api", "lib/dao/api/context.rb", "lib/dao/api/dsl.rb", "lib/dao/api/endpoints.rb", "lib/dao/api/initializers.rb", "lib/dao/api/modes.rb", "lib/dao/api.rb", "lib/dao/blankslate.rb", "lib/dao/data.rb", "lib/dao/db.rb", "lib/dao/endpoint.rb", "lib/dao/engine.rb", "lib/dao/errors.rb", "lib/dao/exceptions.rb", "lib/dao/form.rb", "lib/dao/mode.rb", "lib/dao/mongo_mapper.rb", "lib/dao/params.rb", "lib/dao/path.rb", "lib/dao/rails", "lib/dao/rails/app", "lib/dao/rails/app/api.rb", "lib/dao/rails/app/controllers", "lib/dao/rails/app/controllers/api_controller.rb", "lib/dao/rails/engine", "lib/dao/rails/lib", "lib/dao/rails/lib/generators", "lib/dao/rails/lib/generators/dao", "lib/dao/rails/lib/generators/dao/api_generator.rb", "lib/dao/rails/lib/generators/dao/dao_generator.rb", "lib/dao/rails/lib/generators/dao/templates", "lib/dao/rails/lib/generators/dao/templates/api.rb", "lib/dao/rails/lib/generators/dao/templates/api_controller.rb", "lib/dao/rails/lib/generators/dao/USAGE", "lib/dao/rails.rb", "lib/dao/result.rb", "lib/dao/slug.rb", "lib/dao/status.rb", "lib/dao/stdext.rb", "lib/dao/support.rb", "lib/dao/validations.rb", "lib/dao.rb", "Rakefile", "README", "sample", "sample/rails_app", "sample/rails_app/app", "sample/rails_app/app/api.rb", "sample/rails_app/app/controllers", "sample/rails_app/app/controllers/api_controller.rb", "sample/rails_app/app/controllers/application_controller.rb", "sample/rails_app/app/helpers", "sample/rails_app/app/helpers/application_helper.rb", "sample/rails_app/app/mailers", "sample/rails_app/app/models", "sample/rails_app/app/views", "sample/rails_app/app/views/layouts", "sample/rails_app/app/views/layouts/application.html.erb", "sample/rails_app/config", "sample/rails_app/config/application.rb", "sample/rails_app/config/boot.rb", "sample/rails_app/config/database.yml", "sample/rails_app/config/environment.rb", "sample/rails_app/config/environments", "sample/rails_app/config/environments/development.rb", "sample/rails_app/config/environments/production.rb", "sample/rails_app/config/environments/test.rb", "sample/rails_app/config/initializers", "sample/rails_app/config/initializers/backtrace_silencers.rb", "sample/rails_app/config/initializers/inflections.rb", "sample/rails_app/config/initializers/mime_types.rb", "sample/rails_app/config/initializers/secret_token.rb", "sample/rails_app/config/initializers/session_store.rb", "sample/rails_app/config/locales", "sample/rails_app/config/locales/en.yml", "sample/rails_app/config/routes.rb", "sample/rails_app/config.ru", "sample/rails_app/db", "sample/rails_app/db/development.sqlite3", "sample/rails_app/db/seeds.rb", "sample/rails_app/doc", "sample/rails_app/doc/README_FOR_APP", "sample/rails_app/Gemfile", "sample/rails_app/Gemfile.lock", "sample/rails_app/lib", "sample/rails_app/lib/tasks", "sample/rails_app/log", "sample/rails_app/log/development.log", "sample/rails_app/log/production.log", "sample/rails_app/log/server.log", "sample/rails_app/log/test.log", "sample/rails_app/public", "sample/rails_app/public/404.html", "sample/rails_app/public/422.html", "sample/rails_app/public/500.html", "sample/rails_app/public/favicon.ico", "sample/rails_app/public/images", "sample/rails_app/public/images/rails.png", "sample/rails_app/public/index.html", "sample/rails_app/public/javascripts", "sample/rails_app/public/javascripts/application.js", "sample/rails_app/public/javascripts/controls.js", "sample/rails_app/public/javascripts/dragdrop.js", "sample/rails_app/public/javascripts/effects.js", "sample/rails_app/public/javascripts/prototype.js", "sample/rails_app/public/javascripts/rails.js", "sample/rails_app/public/robots.txt", "sample/rails_app/public/stylesheets", "sample/rails_app/Rakefile", "sample/rails_app/README", "sample/rails_app/script", "sample/rails_app/script/rails", "sample/rails_app/test", "sample/rails_app/test/fixtures", "sample/rails_app/test/functional", "sample/rails_app/test/integration", "sample/rails_app/test/performance", "sample/rails_app/test/performance/browsing_test.rb", "sample/rails_app/test/test_helper.rb", "sample/rails_app/test/unit", "sample/rails_app/tmp/cache", "sample/rails_app/tmp/pids", "sample/rails_app/tmp/sessions", "sample/rails_app/tmp/sockets", "sample/rails_app/vendor", "sample/rails_app/vendor/plugins", "test", "test/dao_test.rb", "test/helper.rb", "test/testing.rb", "test/units", "TODO"]
11
+ spec.files = ["dao.gemspec", "lib", "lib/dao", "lib/dao/active_record.rb", "lib/dao/api", "lib/dao/api/context.rb", "lib/dao/api/dsl.rb", "lib/dao/api/endpoints.rb", "lib/dao/api/initializers.rb", "lib/dao/api/interfaces.rb", "lib/dao/api/modes.rb", "lib/dao/api.rb", "lib/dao/blankslate.rb", "lib/dao/data.rb", "lib/dao/db.rb", "lib/dao/endpoint.rb", "lib/dao/engine.rb", "lib/dao/errors.rb", "lib/dao/exceptions.rb", "lib/dao/form.rb", "lib/dao/instance_exec.rb", "lib/dao/interface.rb", "lib/dao/mode.rb", "lib/dao/mongo_mapper.rb", "lib/dao/params.rb", "lib/dao/path.rb", "lib/dao/rails", "lib/dao/rails/app", "lib/dao/rails/app/api.rb", "lib/dao/rails/app/controllers", "lib/dao/rails/app/controllers/api_controller.rb", "lib/dao/rails/engine", "lib/dao/rails/lib", "lib/dao/rails/lib/generators", "lib/dao/rails/lib/generators/dao", "lib/dao/rails/lib/generators/dao/api_generator.rb", "lib/dao/rails/lib/generators/dao/dao_generator.rb", "lib/dao/rails/lib/generators/dao/templates", "lib/dao/rails/lib/generators/dao/templates/api.rb", "lib/dao/rails/lib/generators/dao/templates/api_controller.rb", "lib/dao/rails/lib/generators/dao/templates/dao.css", "lib/dao/rails/lib/generators/dao/templates/dao.js", "lib/dao/rails/lib/generators/dao/templates/dao_helper.rb", "lib/dao/rails/lib/generators/dao/USAGE", "lib/dao/rails.rb", "lib/dao/result.rb", "lib/dao/slug.rb", "lib/dao/status.rb", "lib/dao/stdext.rb", "lib/dao/support.rb", "lib/dao/validations.rb", "lib/dao.rb", "Rakefile", "README", "sample", "sample/rails_app", "sample/rails_app/app", "sample/rails_app/app/api.rb", "sample/rails_app/app/controllers", "sample/rails_app/app/controllers/api_controller.rb", "sample/rails_app/app/controllers/application_controller.rb", "sample/rails_app/app/helpers", "sample/rails_app/app/helpers/application_helper.rb", "sample/rails_app/app/mailers", "sample/rails_app/app/models", "sample/rails_app/app/views", "sample/rails_app/app/views/layouts", "sample/rails_app/app/views/layouts/application.html.erb", "sample/rails_app/config", "sample/rails_app/config/application.rb", "sample/rails_app/config/boot.rb", "sample/rails_app/config/database.yml", "sample/rails_app/config/environment.rb", "sample/rails_app/config/environments", "sample/rails_app/config/environments/development.rb", "sample/rails_app/config/environments/production.rb", "sample/rails_app/config/environments/test.rb", "sample/rails_app/config/initializers", "sample/rails_app/config/initializers/backtrace_silencers.rb", "sample/rails_app/config/initializers/inflections.rb", "sample/rails_app/config/initializers/mime_types.rb", "sample/rails_app/config/initializers/secret_token.rb", "sample/rails_app/config/initializers/session_store.rb", "sample/rails_app/config/locales", "sample/rails_app/config/locales/en.yml", "sample/rails_app/config/routes.rb", "sample/rails_app/config.ru", "sample/rails_app/db", "sample/rails_app/db/development.sqlite3", "sample/rails_app/db/seeds.rb", "sample/rails_app/doc", "sample/rails_app/doc/README_FOR_APP", "sample/rails_app/Gemfile", "sample/rails_app/Gemfile.lock", "sample/rails_app/lib", "sample/rails_app/lib/tasks", "sample/rails_app/log", "sample/rails_app/log/development.log", "sample/rails_app/log/production.log", "sample/rails_app/log/server.log", "sample/rails_app/log/test.log", "sample/rails_app/pubic", "sample/rails_app/pubic/javascripts", "sample/rails_app/pubic/javascripts/dao.js", "sample/rails_app/public", "sample/rails_app/public/404.html", "sample/rails_app/public/422.html", "sample/rails_app/public/500.html", "sample/rails_app/public/favicon.ico", "sample/rails_app/public/images", "sample/rails_app/public/images/rails.png", "sample/rails_app/public/index.html", "sample/rails_app/public/javascripts", "sample/rails_app/public/javascripts/application.js", "sample/rails_app/public/javascripts/controls.js", "sample/rails_app/public/javascripts/dragdrop.js", "sample/rails_app/public/javascripts/effects.js", "sample/rails_app/public/javascripts/prototype.js", "sample/rails_app/public/javascripts/rails.js", "sample/rails_app/public/robots.txt", "sample/rails_app/public/stylesheets", "sample/rails_app/Rakefile", "sample/rails_app/README", "sample/rails_app/script", "sample/rails_app/script/rails", "sample/rails_app/test", "sample/rails_app/test/fixtures", "sample/rails_app/test/functional", "sample/rails_app/test/integration", "sample/rails_app/test/performance", "sample/rails_app/test/performance/browsing_test.rb", "sample/rails_app/test/test_helper.rb", "sample/rails_app/test/unit", "sample/rails_app/tmp/cache", "sample/rails_app/tmp/pids", "sample/rails_app/tmp/sessions", "sample/rails_app/tmp/sockets", "sample/rails_app/vendor", "sample/rails_app/vendor/plugins", "test", "test/dao_test.rb", "test/helper.rb", "test/testing.rb", "test/units"]
12
12
  spec.executables = []
13
13
 
14
14
  spec.require_path = "lib"
15
15
 
16
16
  spec.has_rdoc = true
17
- spec.test_files = nil
18
17
 
19
- # spec.add_dependency 'lib', '>= version'
20
- spec.add_dependency 'map'
21
- spec.add_dependency 'tagz'
22
- spec.add_dependency 'yajl-ruby'
18
+
19
+
20
+
21
+ spec.add_dependency(*["tagz", "~> 8.2.0"])
22
+
23
+ spec.add_dependency(*["map", "~> 2.6.1"])
24
+
25
+ spec.add_dependency(*["yajl-ruby", "~> 0.7.9"])
26
+
23
27
 
24
28
  spec.extensions.push(*[])
25
29
 
data/lib/dao.rb CHANGED
@@ -6,33 +6,23 @@
6
6
  #require 'yaml'
7
7
  #require 'yaml/store'
8
8
 
9
- # gems
10
- #
11
- begin
12
- require 'rubygems'
13
- rescue LoadError
14
- nil
15
- end
16
-
17
- if defined?(gem)
18
- gem('map', '~> 2.2.2')
19
- gem('tagz', '~> 8.0')
20
- gem('yajl-ruby', '~> 0.7.9')
21
- end
22
-
23
- require 'map'
24
- require 'tagz'
25
- require 'yajl'
26
-
27
9
  # dao libs
28
10
  #
29
11
  module Dao
30
- Version = '2.0.0' unless defined?(Version)
12
+ Version = '2.1.0' unless defined?(Version)
31
13
 
32
14
  def version
33
15
  Dao::Version
34
16
  end
35
17
 
18
+ def dependencies
19
+ {
20
+ 'map' => ['map', '~> 2.6.1'],
21
+ 'tagz' => ['tagz', '~> 8.2.0'],
22
+ 'yajl' => ['yajl-ruby', '~> 0.7.9']
23
+ }
24
+ end
25
+
36
26
  def libdir(*args, &block)
37
27
  @libdir ||= File.expand_path(__FILE__).sub(/\.rb$/,'')
38
28
  args.empty? ? @libdir : File.join(@libdir, *args)
@@ -55,8 +45,24 @@
55
45
  extend(Dao)
56
46
  end
57
47
 
48
+ # gems
49
+ #
50
+ begin
51
+ require 'rubygems'
52
+ rescue LoadError
53
+ nil
54
+ end
55
+
56
+ if defined?(gem)
57
+ Dao.dependencies.each do |lib, dependency|
58
+ gem(*dependency)
59
+ require(lib)
60
+ end
61
+ end
62
+
58
63
  Dao.load %w[
59
64
  blankslate.rb
65
+ instance_exec.rb
60
66
  exceptions.rb
61
67
  support.rb
62
68
  slug.rb
@@ -72,7 +78,7 @@
72
78
 
73
79
  mode.rb
74
80
  path.rb
75
- endpoint.rb
81
+ interface.rb
76
82
  api.rb
77
83
 
78
84
 
@@ -86,3 +92,10 @@
86
92
  unless defined?(D)
87
93
  D = Dao
88
94
  end
95
+
96
+ if defined?(Rails.env)
97
+ unless Rails.env.production?
98
+ unloadable(Dao)
99
+ unloadable(D)
100
+ end
101
+ end
@@ -8,68 +8,76 @@ end
8
8
  if defined?(ActiveRecord)
9
9
 
10
10
  module ActiveRecord
11
- module ToDao
12
- module ClassMethods
13
- def to_dao(*args)
14
-
11
+ class Base
12
+ def Base.to_dao(*args)
13
+ if args.first.is_a?(Base)
14
+ record_to_dao(record = args.shift, *args)
15
+ else
15
16
  @to_dao ||= (
16
- column_names # + reflect_on_all_associations.map(&:name)
17
- ).map{|name| name.to_s}
18
-
19
- unless args.empty?
20
- @to_dao.clear
21
- args.flatten.compact.each do |arg|
22
- @to_dao.push(arg.to_s)
23
- end
24
- @to_dao.uniq!
25
- @to_dao.map!{|name| name.to_s}
26
- end
27
-
17
+ names = column_names ### + reflect_on_all_associations.map(&:name)
18
+ )
19
+ @to_dao = Array(args) unless args.empty?
28
20
  @to_dao
29
21
  end
22
+ end
30
23
 
31
- def to_dao=(*args)
32
- to_dao(*args)
33
- end
24
+ def Base.to_dao=(*args)
25
+ to_dao(*args)
34
26
  end
35
27
 
36
- module InstanceMethods
37
- def to_dao(*args)
38
- hash = Dao.hash
39
- model = self.class
28
+ def Base.record_to_dao(record, *args)
29
+ model = record.class
30
+ map = Dao.map
31
+ map[:model] = model.name.underscore
32
+ map[:id] = record.id
40
33
 
41
- attrs = args.empty? ? model.to_dao : args
34
+ list = args.empty? ? model.to_dao : args
42
35
 
43
- attrs.each do |attr|
44
- value = send(attr)
36
+ list.each do |attr|
37
+ if attr.is_a?(Array)
38
+ related, *argv = attr
39
+ value = record.send(related).to_dao(*argv)
40
+ map[related] = value
41
+ next
42
+ end
45
43
 
46
- if value.respond_to?(:to_dao)
47
- hash[attr] = value.to_dao
48
- next
44
+ if attr.is_a?(Hash)
45
+ attr.each do |related, argv|
46
+ value = record.send(related).to_dao(*argv)
47
+ map[related] = value
49
48
  end
49
+ next
50
+ end
50
51
 
51
- if value.is_a?(Array)
52
- hash[attr] = value.map{|val| val.respond_to?(:to_dao) ? val.to_dao : val}
53
- next
54
- end
52
+ value = record.send(attr)
55
53
 
56
- hash[attr] = value
54
+ if value.respond_to?(:to_dao)
55
+ map[attr] = value.to_dao
56
+ next
57
57
  end
58
58
 
59
- if hash.has_key?(:_id) and not hash.has_key?(:id)
60
- hash[:id] = hash[:_id]
59
+ if value.is_a?(Array)
60
+ map[attr] = value.map{|val| val.respond_to?(:to_dao) ? val.to_dao : val}
61
+ next
61
62
  end
62
63
 
63
- hash
64
+ map[attr] = value
65
+ end
66
+
67
+ if map.has_key?(:_id) and not map.has_key?(:id)
68
+ map[:id] = map[:_id]
64
69
  end
65
- alias_method 'to_h', 'to_dao'
66
- #alias_method 'to_map', 'to_dao' ### HACK
70
+
71
+ map
67
72
  end
68
- end
69
73
 
70
- if defined?(ActiveRecord::Base)
71
- ActiveRecord::Base.send(:extend, ToDao::ClassMethods)
72
- ActiveRecord::Base.send(:include, ToDao::InstanceMethods)
74
+ def to_dao(*args)
75
+ record = self
76
+ model = record.class
77
+ model.record_to_dao(record, *args)
78
+ end
79
+ alias_method('to_h', 'to_dao')
80
+ alias_method('to_map', 'to_dao') ### HACK
73
81
  end
74
82
  end
75
83