dao 0.0.0 → 2.0.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.
Files changed (90) hide show
  1. data/README +35 -0
  2. data/Rakefile +6 -3
  3. data/TODO +37 -0
  4. data/dao.gemspec +30 -0
  5. data/db/dao.yml +8 -0
  6. data/lib/dao.rb +84 -5
  7. data/lib/dao/active_record.rb +76 -0
  8. data/lib/dao/api.rb +9 -0
  9. data/lib/dao/api/context.rb +38 -0
  10. data/lib/dao/api/dsl.rb +50 -0
  11. data/lib/dao/api/endpoints.rb +190 -0
  12. data/lib/dao/api/initializers.rb +71 -0
  13. data/lib/dao/api/modes.rb +85 -0
  14. data/lib/dao/blankslate.rb +5 -0
  15. data/lib/dao/data.rb +58 -0
  16. data/lib/dao/db.rb +183 -0
  17. data/lib/dao/endpoint.rb +16 -0
  18. data/lib/dao/engine.rb +7 -0
  19. data/lib/dao/errors.rb +238 -0
  20. data/lib/dao/exceptions.rb +2 -0
  21. data/lib/dao/form.rb +236 -0
  22. data/lib/dao/mode.rb +41 -0
  23. data/lib/dao/mongo_mapper.rb +70 -0
  24. data/lib/dao/params.rb +109 -0
  25. data/lib/dao/path.rb +149 -0
  26. data/lib/dao/rails.rb +15 -0
  27. data/lib/dao/rails/app/api.rb +55 -0
  28. data/lib/dao/rails/app/controllers/api_controller.rb +99 -0
  29. data/lib/dao/rails/lib/generators/dao/USAGE +9 -0
  30. data/lib/dao/rails/lib/generators/dao/api_generator.rb +3 -0
  31. data/lib/dao/rails/lib/generators/dao/dao_generator.rb +27 -0
  32. data/lib/dao/rails/lib/generators/dao/templates/api.rb +55 -0
  33. data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +99 -0
  34. data/lib/dao/result.rb +87 -0
  35. data/lib/dao/slug.rb +11 -0
  36. data/lib/dao/status.rb +223 -0
  37. data/lib/dao/stdext.rb +10 -0
  38. data/lib/dao/support.rb +62 -0
  39. data/lib/dao/validations.rb +115 -0
  40. data/sample/rails_app/Gemfile +33 -0
  41. data/sample/rails_app/Gemfile.lock +88 -0
  42. data/sample/rails_app/README +1 -0
  43. data/sample/rails_app/Rakefile +7 -0
  44. data/sample/rails_app/app/api.rb +55 -0
  45. data/sample/rails_app/app/controllers/api_controller.rb +99 -0
  46. data/sample/rails_app/app/controllers/application_controller.rb +3 -0
  47. data/sample/rails_app/app/helpers/application_helper.rb +2 -0
  48. data/sample/rails_app/app/views/layouts/application.html.erb +14 -0
  49. data/sample/rails_app/config.ru +4 -0
  50. data/sample/rails_app/config/application.rb +51 -0
  51. data/sample/rails_app/config/boot.rb +13 -0
  52. data/sample/rails_app/config/database.yml +22 -0
  53. data/sample/rails_app/config/environment.rb +5 -0
  54. data/sample/rails_app/config/environments/development.rb +26 -0
  55. data/sample/rails_app/config/environments/production.rb +49 -0
  56. data/sample/rails_app/config/environments/test.rb +35 -0
  57. data/sample/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  58. data/sample/rails_app/config/initializers/inflections.rb +10 -0
  59. data/sample/rails_app/config/initializers/mime_types.rb +5 -0
  60. data/sample/rails_app/config/initializers/secret_token.rb +7 -0
  61. data/sample/rails_app/config/initializers/session_store.rb +8 -0
  62. data/sample/rails_app/config/locales/en.yml +5 -0
  63. data/sample/rails_app/config/routes.rb +62 -0
  64. data/sample/rails_app/db/development.sqlite3 +0 -0
  65. data/sample/rails_app/db/seeds.rb +7 -0
  66. data/sample/rails_app/doc/README_FOR_APP +2 -0
  67. data/sample/rails_app/log/development.log +27 -0
  68. data/sample/rails_app/log/production.log +0 -0
  69. data/sample/rails_app/log/server.log +0 -0
  70. data/sample/rails_app/log/test.log +0 -0
  71. data/sample/rails_app/public/404.html +26 -0
  72. data/sample/rails_app/public/422.html +26 -0
  73. data/sample/rails_app/public/500.html +26 -0
  74. data/sample/rails_app/public/favicon.ico +0 -0
  75. data/sample/rails_app/public/images/rails.png +0 -0
  76. data/sample/rails_app/public/index.html +239 -0
  77. data/sample/rails_app/public/javascripts/application.js +2 -0
  78. data/sample/rails_app/public/javascripts/controls.js +965 -0
  79. data/sample/rails_app/public/javascripts/dragdrop.js +974 -0
  80. data/sample/rails_app/public/javascripts/effects.js +1123 -0
  81. data/sample/rails_app/public/javascripts/prototype.js +6001 -0
  82. data/sample/rails_app/public/javascripts/rails.js +175 -0
  83. data/sample/rails_app/public/robots.txt +5 -0
  84. data/sample/rails_app/script/rails +6 -0
  85. data/sample/rails_app/test/performance/browsing_test.rb +9 -0
  86. data/sample/rails_app/test/test_helper.rb +13 -0
  87. data/test/dao_test.rb +271 -0
  88. data/test/helper.rb +15 -0
  89. data/test/testing.rb +74 -0
  90. metadata +137 -9
@@ -0,0 +1,2 @@
1
+ class Error < ::StandardError
2
+ end
data/lib/dao/form.rb ADDED
@@ -0,0 +1,236 @@
1
+ module Dao
2
+ class Form
3
+ include Tagz.globally
4
+
5
+ class << Form
6
+ def for(*args, &block)
7
+ new(*args, &block)
8
+ end
9
+
10
+ def cast(*args)
11
+ if args.size == 1
12
+ value = args.first
13
+ value.is_a?(self) ? value : self.for(value)
14
+ else
15
+ self.for(*args)
16
+ end
17
+ end
18
+ end
19
+
20
+ attr_accessor :result
21
+
22
+ def initialize(*args, &block)
23
+ @result = args.shift if args.first.is_a?(Result)
24
+ super
25
+ end
26
+
27
+ def params
28
+ result.params
29
+ end
30
+
31
+ def ==(other)
32
+ params.object_id == other.params.object_id
33
+ end
34
+
35
+ def errors
36
+ result.errors
37
+ end
38
+
39
+ def form(*args, &block)
40
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
41
+ keys = args.flatten
42
+
43
+ action = options.delete(:action) || './'
44
+ method = options.delete(:method) || 'post'
45
+ id = options.delete(:id) || id_for(keys)
46
+ klass = class_for(keys, options.delete(:class))
47
+ error = error_for(keys, options.delete(:error))
48
+
49
+ content =
50
+ if block.nil? and !options.has_key?(:content)
51
+ ''
52
+ else
53
+ block ? block.call(form=self) : options.delete(:content)
54
+ end
55
+
56
+ form_(options_for(options, :action => action, :method => method, :class => klass, :id => id, :data_error => error)){ content }
57
+ end
58
+
59
+ def label(*args, &block)
60
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
61
+ keys = args.flatten
62
+
63
+ name = options.delete(:name) || keys.last
64
+ id = options.delete(:id) || id_for(keys)
65
+ klass = class_for(keys, options.delete(:class))
66
+ error = error_for(keys, options.delete(:error))
67
+
68
+ content =
69
+ if block.nil? and !options.has_key?(:content)
70
+ name.to_s.humanize
71
+ else
72
+ block ? block.call() : options.delete(:content)
73
+ end
74
+
75
+ label_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){ content }
76
+ end
77
+
78
+ def input(*args, &block)
79
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
80
+ keys = args.flatten
81
+
82
+ type = options.delete(:type) || :text
83
+ name = options.delete(:name) || name_for(keys)
84
+ id = options.delete(:id) || id_for(keys)
85
+ klass = class_for(keys, options.delete(:class))
86
+ error = error_for(keys, options.delete(:error))
87
+
88
+ value =
89
+ if block.nil? and !options.has_key?(:value)
90
+ value_for(params, keys)
91
+ else
92
+ block ? block.call(params.get(keys)) : options.delete(:value)
93
+ end
94
+
95
+ input_(options_for(options, :type => type, :name => name, :value => value, :class => klass, :id => id, :data_error => error)){}
96
+ end
97
+
98
+ def submit(*args, &block)
99
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
100
+ options[:type] = :submit
101
+ options[:value] = block ? block.call : :Submit
102
+ args.push(options)
103
+ input(*args)
104
+ end
105
+
106
+ def button(*args)
107
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
108
+ keys = args.flatten
109
+
110
+ type = options.delete(:type) || :button
111
+ name = options.delete(:name) || name_for(keys)
112
+ id = options.delete(:id) || id_for(keys)
113
+ klass = class_for(keys, options.delete(:class))
114
+ error = error_for(keys, options.delete(:error))
115
+
116
+ value =
117
+ if block.nil? and !options.has_key?(:value)
118
+ value_for(params, keys)
119
+ else
120
+ block ? block.call(params.get(keys)) : options.delete(:value)
121
+ end
122
+
123
+ button_(options_for(options, :type => type, :name => name, :value => value, :class => klass, :id => id, :data_error => error)){}
124
+ end
125
+
126
+ def reset(*args)
127
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
128
+ options[:type] = :reset
129
+ args.push(options)
130
+ button(*args)
131
+ end
132
+
133
+ def textarea(*args, &block)
134
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
135
+ keys = args.flatten
136
+
137
+ name = options.delete(:name) || name_for(keys)
138
+ id = options.delete(:id) || id_for(keys)
139
+ klass = class_for(keys, options.delete(:class))
140
+ error = error_for(keys, options.delete(:error))
141
+
142
+ value =
143
+ if block.nil? and !options.has_key?(:value)
144
+ value_for(params, keys)
145
+ else
146
+ block ? block.call(params.get(keys)) : options.delete(:value)
147
+ end
148
+
149
+ textarea_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){ value }
150
+ end
151
+
152
+ def select(*args, &block)
153
+ options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
154
+ keys = args.flatten
155
+
156
+ name = options.delete(:name) || name_for(keys)
157
+ from = options.delete(:from) || options.delete(:select) || options.delete(:all) || options.delete(:list)
158
+
159
+ id = options.delete(:id) || id_for(keys)
160
+ klass = class_for(keys, options.delete(:class))
161
+ error = error_for(keys, options.delete(:error))
162
+
163
+ select_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){
164
+ pairs = Array(params[from]).flatten
165
+ pairs.each do |pair|
166
+ result = block.call(pair)
167
+ case result
168
+ when Array
169
+ value, content, selected, *ignored = result
170
+ when Hash
171
+ value = result[:value]
172
+ content = result[:content] || value
173
+ selected = result[:selected]
174
+ else
175
+ value = result
176
+ content = result
177
+ selected = false
178
+ end
179
+ opts = {:value => value}
180
+ opts[:selected] = !!selected if selected
181
+ option_(opts){ content }
182
+ end
183
+ }
184
+ end
185
+
186
+ def id_for(keys)
187
+ id = [result.path, keys.join('-')].compact.join('_')
188
+ slug_for(id)
189
+ end
190
+
191
+ def class_for(keys, klass = nil)
192
+ klass =
193
+ if result.errors.on?(keys)
194
+ [klass, 'dao', 'errors'].compact.join(' ')
195
+ else
196
+ [klass, 'dao'].compact.join(' ')
197
+ end
198
+ klass
199
+ end
200
+
201
+ def error_for(keys, klass = nil)
202
+ if result.errors.on?(keys)
203
+ result.errors.get(keys)
204
+ end
205
+ end
206
+
207
+ def value_for(params, keys)
208
+ return nil unless params.has?(keys)
209
+ value = Tagz.escapeHTML(params.get(keys))
210
+ end
211
+
212
+ def name_for(keys)
213
+ "#{ result.path }(#{ Array(keys).flatten.compact.join(',') })"
214
+ end
215
+
216
+ def options_for(*hashes)
217
+ map = Map.new
218
+ hashes.flatten.each do |h|
219
+ h.each{|k,v| map[attr_for(k)] = v unless v.nil?}
220
+ end
221
+ map
222
+ end
223
+
224
+ def slug_for(string)
225
+ string = string.to_s
226
+ words = string.to_s.scan(%r/\w+/)
227
+ words.map!{|word| word.gsub(%r/[^0-9a-zA-Z_:-]/, '')}
228
+ words.delete_if{|word| word.nil? or word.strip.empty?}
229
+ words.join('-').downcase.sub(/_+$/, '')
230
+ end
231
+
232
+ def attr_for(string)
233
+ slug_for(string).gsub(/_/, '-')
234
+ end
235
+ end
236
+ end
data/lib/dao/mode.rb ADDED
@@ -0,0 +1,41 @@
1
+ module Dao
2
+ class Mode < ::String
3
+ class << Mode
4
+ def for(mode)
5
+ mode.is_a?(Mode) ? mode : Mode.new(mode.to_s)
6
+ end
7
+
8
+ def list
9
+ List
10
+ end
11
+
12
+ def default
13
+ Mode.for(:read)
14
+ end
15
+ end
16
+
17
+ Verbs = %w( options get head post put delete trace connect )
18
+
19
+ Verbs.each do |verb|
20
+ const = verb.downcase.capitalize
21
+ unless const_defined?(const)
22
+ mode = Mode.for(verb.downcase)
23
+ const_set(const, mode)
24
+ end
25
+ end
26
+
27
+ Read = Get unless defined?(Read)
28
+ Write = Post unless defined?(Write)
29
+
30
+ List = Verbs + %w( read write )
31
+
32
+ List.each do |method|
33
+ const = method.downcase.capitalize
34
+ define_method(method){ const_get(const) }
35
+ end
36
+
37
+ def ==(other)
38
+ super(Mode.for(other))
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,70 @@
1
+ begin
2
+ MongoMapper
3
+ rescue NameError
4
+ nil
5
+ end
6
+
7
+ if defined?(MongoMapper)
8
+
9
+ module MongoMapper
10
+ module ToDao
11
+ module ClassMethods
12
+ def to_dao(*args)
13
+
14
+ unless defined?(@to_dao)
15
+ @to_dao = column_names.map{|name| name.to_s}
16
+ end
17
+
18
+ unless args.empty?
19
+ @to_dao.clear
20
+ args.flatten.compact.each do |arg|
21
+ @to_dao.push(arg.to_s)
22
+ end
23
+ @to_dao.uniq!
24
+ @to_dao.map!{|name| name.to_s}
25
+ end
26
+
27
+ @to_dao
28
+ end
29
+ end
30
+
31
+ module InstanceMethods
32
+ def to_dao(*args)
33
+ hash = Dao.hash
34
+ model = self.class
35
+
36
+ attrs = args.empty? ? model.to_dao : args
37
+
38
+ attrs.each do |attr|
39
+ value = send(attr)
40
+
41
+ if value.respond_to?(:to_dao)
42
+ hash[attr] = value.to_dao
43
+ next
44
+ end
45
+
46
+ if value.is_a?(Array)
47
+ hash[attr] = value.map{|val| val.respond_to?(:to_dao) ? val.to_dao : val}
48
+ next
49
+ end
50
+
51
+ hash[attr] = value
52
+ end
53
+
54
+ if hash.has_key?(:_id) and not hash.has_key?(:id)
55
+ hash[:id] = hash[:_id]
56
+ end
57
+
58
+ hash
59
+ end
60
+ alias_method 'to_h', 'to_dao'
61
+ end
62
+ end
63
+
64
+ MongoMapper::Document::ClassMethods.send(:include, ToDao::ClassMethods)
65
+ MongoMapper::Document::InstanceMethods.send(:include, ToDao::InstanceMethods)
66
+ MongoMapper::EmbeddedDocument::ClassMethods.send(:include, ToDao::ClassMethods)
67
+ MongoMapper::EmbeddedDocument::InstanceMethods.send(:include, ToDao::InstanceMethods)
68
+ end
69
+
70
+ end
data/lib/dao/params.rb ADDED
@@ -0,0 +1,109 @@
1
+ module Dao
2
+ class Params < ::Map
3
+ class << Params
4
+ def parse(prefix, params = {})
5
+ prefix = prefix.to_s
6
+ params = Map.new(params)
7
+ parsed = Params.new
8
+ parsed.update(params[prefix]) if params.has_key?(prefix)
9
+
10
+ re = %r/^ #{ Regexp.escape(prefix) } (?: [(] ([^)]+) [)] )? $/x
11
+
12
+ params.each do |key, value|
13
+ next unless(key.is_a?(String) or key.is_a?(Symbol))
14
+ key = key.to_s
15
+ matched, keys = re.match(key).to_a
16
+ next unless matched
17
+ next unless keys
18
+ keys = keys.strip.split(%r/\s*,\s*/).map{|key| key =~ %r/^\d+$/ ? Integer(key) : key}
19
+ parsed.set(keys => value)
20
+ end
21
+
22
+ parsed
23
+ end
24
+ end
25
+
26
+ attr_accessor :api
27
+ attr_accessor :endpoint
28
+ attr_accessor :params
29
+ attr_accessor :result
30
+
31
+ def Params.for(*args, &block)
32
+ options = Dao.options_for!(args)
33
+
34
+ api = options[:api]
35
+ endpoint = options[:endpoint]
36
+ updates = options[:params]
37
+
38
+ params = new()
39
+ params.api = api
40
+ params.endpoint = endpoint
41
+
42
+ params.update(updates) if updates
43
+
44
+ params
45
+ end
46
+
47
+ def path
48
+ result.path if result
49
+ end
50
+
51
+ def status(*args)
52
+ result.status(*args) if result
53
+ end
54
+ def status=(value)
55
+ result.status=value if result
56
+ end
57
+
58
+ def errors
59
+ result.errors if result
60
+ end
61
+
62
+ def data
63
+ result.data if result
64
+ end
65
+
66
+ def validates(*args, &block)
67
+ result.validates(*args, &block) if result
68
+ end
69
+
70
+ def validate(*args, &block)
71
+ result.validate(*args, &block) if result
72
+ end
73
+
74
+ def valid?
75
+ result.valid? if result
76
+ end
77
+
78
+ def validate!
79
+ result.validate! if result
80
+ end
81
+
82
+ unless Object.new.respond_to?(:instance_exec)
83
+ module InstanceExecHelper; end
84
+ include InstanceExecHelper
85
+
86
+ def instance_exec(*args, &block)
87
+ begin
88
+ old_critical, Thread.critical = Thread.critical, true
89
+ n = 0
90
+ n += 1 while respond_to?(mname="__instance_exec_#{ n }__")
91
+ InstanceExecHelper.module_eval{ define_method(mname, &block) }
92
+ ensure
93
+ Thread.critical = old_critical
94
+ end
95
+ begin
96
+ ret = send(mname, *args)
97
+ ensure
98
+ InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
99
+ end
100
+ ret
101
+ end
102
+ end
103
+ end
104
+
105
+
106
+ def Dao.parse(*args, &block)
107
+ Params.parse(*args, &block)
108
+ end
109
+ end