dao 2.0.0 → 2.1.0

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.
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