dao 0.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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