dao 2.2.3 → 3.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.
Files changed (79) hide show
  1. data/Rakefile +68 -113
  2. data/TODO +3 -9
  3. data/a.rb +25 -0
  4. data/dao.gemspec +70 -14
  5. data/lib/dao.rb +8 -8
  6. data/lib/dao/api.rb +1 -0
  7. data/lib/dao/api/context.rb +48 -23
  8. data/lib/dao/api/dsl.rb +1 -1
  9. data/lib/dao/api/interfaces.rb +149 -117
  10. data/lib/dao/api/modes.rb +24 -23
  11. data/lib/dao/api/routes.rb +9 -0
  12. data/lib/dao/data.rb +9 -2
  13. data/lib/dao/errors.rb +15 -11
  14. data/lib/dao/form.rb +46 -37
  15. data/lib/dao/interface.rb +1 -1
  16. data/lib/dao/mode.rb +45 -20
  17. data/lib/dao/params.rb +35 -53
  18. data/lib/dao/path.rb +6 -9
  19. data/lib/dao/rails/lib/generators/dao/templates/api.rb +1 -1
  20. data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +16 -0
  21. data/lib/dao/result.rb +26 -133
  22. data/lib/dao/route.rb +87 -0
  23. data/lib/dao/status.rb +96 -94
  24. data/lib/dao/support.rb +5 -3
  25. data/lib/dao/validations.rb +46 -442
  26. data/lib/dao/validations/base.rb +68 -0
  27. data/lib/dao/validations/common.rb +463 -0
  28. data/test/dao_test.rb +214 -33
  29. metadata +20 -112
  30. data/lib/dao/rails/app/api.rb +0 -55
  31. data/lib/dao/rails/app/controllers/api_controller.rb +0 -99
  32. data/sample/rails_app/Gemfile +0 -33
  33. data/sample/rails_app/Gemfile.lock +0 -88
  34. data/sample/rails_app/README +0 -1
  35. data/sample/rails_app/Rakefile +0 -7
  36. data/sample/rails_app/app/api.rb +0 -55
  37. data/sample/rails_app/app/controllers/api_controller.rb +0 -99
  38. data/sample/rails_app/app/controllers/application_controller.rb +0 -3
  39. data/sample/rails_app/app/helpers/application_helper.rb +0 -2
  40. data/sample/rails_app/app/views/layouts/application.html.erb +0 -14
  41. data/sample/rails_app/config.ru +0 -4
  42. data/sample/rails_app/config/application.rb +0 -51
  43. data/sample/rails_app/config/boot.rb +0 -13
  44. data/sample/rails_app/config/database.yml +0 -22
  45. data/sample/rails_app/config/environment.rb +0 -5
  46. data/sample/rails_app/config/environments/development.rb +0 -26
  47. data/sample/rails_app/config/environments/production.rb +0 -49
  48. data/sample/rails_app/config/environments/test.rb +0 -35
  49. data/sample/rails_app/config/initializers/backtrace_silencers.rb +0 -7
  50. data/sample/rails_app/config/initializers/inflections.rb +0 -10
  51. data/sample/rails_app/config/initializers/mime_types.rb +0 -5
  52. data/sample/rails_app/config/initializers/secret_token.rb +0 -7
  53. data/sample/rails_app/config/initializers/session_store.rb +0 -8
  54. data/sample/rails_app/config/locales/en.yml +0 -5
  55. data/sample/rails_app/config/routes.rb +0 -62
  56. data/sample/rails_app/db/development.sqlite3 +0 -0
  57. data/sample/rails_app/db/seeds.rb +0 -7
  58. data/sample/rails_app/doc/README_FOR_APP +0 -2
  59. data/sample/rails_app/log/development.log +0 -27
  60. data/sample/rails_app/log/production.log +0 -0
  61. data/sample/rails_app/log/server.log +0 -0
  62. data/sample/rails_app/log/test.log +0 -0
  63. data/sample/rails_app/pubic/javascripts/dao.js +0 -148
  64. data/sample/rails_app/public/404.html +0 -26
  65. data/sample/rails_app/public/422.html +0 -26
  66. data/sample/rails_app/public/500.html +0 -26
  67. data/sample/rails_app/public/favicon.ico +0 -0
  68. data/sample/rails_app/public/images/rails.png +0 -0
  69. data/sample/rails_app/public/index.html +0 -239
  70. data/sample/rails_app/public/javascripts/application.js +0 -2
  71. data/sample/rails_app/public/javascripts/controls.js +0 -965
  72. data/sample/rails_app/public/javascripts/dragdrop.js +0 -974
  73. data/sample/rails_app/public/javascripts/effects.js +0 -1123
  74. data/sample/rails_app/public/javascripts/prototype.js +0 -6001
  75. data/sample/rails_app/public/javascripts/rails.js +0 -175
  76. data/sample/rails_app/public/robots.txt +0 -5
  77. data/sample/rails_app/script/rails +0 -6
  78. data/sample/rails_app/test/performance/browsing_test.rb +0 -9
  79. data/sample/rails_app/test/test_helper.rb +0 -13
@@ -1,4 +1,3 @@
1
-
2
1
  module Dao
3
2
  class Api
4
3
  class << Api
@@ -13,34 +12,37 @@ module Dao
13
12
  end
14
13
 
15
14
  def add_mode(mode)
16
- modes.push(mode = Mode.for(mode)).uniq!
17
-
18
- module_eval(<<-__, __FILE__, __LINE__ - 1)
15
+ mode = Mode.for(mode)
19
16
 
20
- def #{ mode }(*args, &block)
21
- if args.empty?
22
- if catching_results?
23
- if self.mode == #{ mode.inspect }
17
+ unless modes.include?(mode)
18
+ module_eval(<<-__, __FILE__, __LINE__ - 1)
19
+ def #{ mode }(*args, &block)
20
+ if args.empty?
21
+ if catching_results?
22
+ if self.mode.case_of?(Mode.for(#{ mode.inspect }))
23
+ mode(#{ mode.inspect }, &block)
24
+ return!
25
+ end
26
+ else
24
27
  mode(#{ mode.inspect }, &block)
25
- return!
26
28
  end
27
29
  else
28
- mode(#{ mode.inspect }, &block)
29
- end
30
- else
31
- mode(#{ mode.inspect }) do
32
- call(*args, &block)
30
+ mode(#{ mode.inspect }) do
31
+ call(*args, &block)
32
+ end
33
33
  end
34
34
  end
35
- end
36
35
 
37
- def #{ mode }?(&block)
38
- mode?(#{ mode.inspect }, &block)
39
- end
40
-
41
- __
36
+ def #{ mode }?(&block)
37
+ mode?(#{ mode.inspect }, &block)
38
+ end
39
+ __
42
40
 
43
- mode
41
+ modes.push(mode)
42
+ mode
43
+ else
44
+ false
45
+ end
44
46
  end
45
47
  end
46
48
 
@@ -70,8 +72,7 @@ module Dao
70
72
  end
71
73
 
72
74
  def mode?(mode, &block)
73
- condition = self.mode == mode
74
-
75
+ condition = mode.case_of?(self.mode)
75
76
  if block.nil?
76
77
  condition
77
78
  else
@@ -0,0 +1,9 @@
1
+ module Dao
2
+ class Api
3
+ class << Api
4
+ def routes
5
+ @routes ||= Route::List.new
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,13 +1,20 @@
1
1
  module Dao
2
2
  class Data < ::Map
3
+ # look good for inspect
4
+ #
5
+ def inspect
6
+ ::JSON.pretty_generate(self, :max_nesting => 0)
7
+ end
8
+
9
+ # support updates with dao-ish objects
10
+ #
3
11
  add_conversion_method!(:to_dao)
4
12
  add_conversion_method!(:as_dao)
5
13
 
6
14
  def update(*args, &block)
7
15
  if args.size==1 and args.first.respond_to?(:to_dao)
8
16
  to_dao = args.first.to_dao
9
- update(to_dao)
10
- return(to_dao)
17
+ return super(to_dao)
11
18
  end
12
19
  super
13
20
  end
@@ -1,14 +1,22 @@
1
1
  module Dao
2
2
  class Errors < ::Map
3
+ # for html generation
4
+ #
3
5
  include Tagz.globally
4
6
 
5
7
  class << Errors
6
8
  include Tagz.globally
7
9
  end
8
10
 
11
+ # you can tweak these if you want
12
+ #
9
13
  Global = '*' unless defined?(Global)
10
- Separator = '⇒' unless defined?(Separator)
14
+ #Separator = '⇒' unless defined?(Separator)
15
+ Separator = "\342\207\222" unless defined?(Separator) ### this is an "Open-outlined rightward arrow" - http://en.wikipedia.org/wiki/List_of_Unicode_characters#Supplemental_arrows-A
11
16
 
17
+
18
+ # string message support class - knows when it's sticky...
19
+ #
12
20
  class Message < ::String
13
21
  attr_accessor :sticky
14
22
 
@@ -28,6 +36,8 @@ module Dao
28
36
  end
29
37
  end
30
38
 
39
+ # class methods
40
+ #
31
41
  class << Errors
32
42
  def global_key
33
43
  [Global]
@@ -36,17 +46,10 @@ module Dao
36
46
  def for(*args, &block)
37
47
  new(*args, &block)
38
48
  end
39
-
40
- def cast(*args)
41
- if args.size == 1
42
- value = args.first
43
- value.is_a?(self) ? value : self.for(value)
44
- else
45
- self.for(*args)
46
- end
47
- end
48
49
  end
49
50
 
51
+ # instance methods
52
+ #
50
53
  def add(*args)
51
54
  options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
52
55
  sticky = options[:sticky]
@@ -113,7 +116,6 @@ module Dao
113
116
  clone
114
117
  end
115
118
 
116
-
117
119
  def update(other, options = {})
118
120
  options = Dao.map_for(options)
119
121
  prefix = Array(options[:prefix]).flatten.compact
@@ -197,6 +199,8 @@ module Dao
197
199
  select{|message| not message.strip.empty?}
198
200
  end
199
201
 
202
+ # html generation methods
203
+ #
200
204
  def to_html(*args)
201
205
  Errors.to_html(errors=self, *args)
202
206
  end
@@ -1,41 +1,41 @@
1
1
  module Dao
2
2
  class Form
3
+ # for html generation
4
+ #
3
5
  include Tagz.globally
4
6
 
7
+ class << Form
8
+ include Tagz.globally
9
+ end
10
+
11
+ # class methods
12
+ #
5
13
  class << Form
6
14
  def for(*args, &block)
7
15
  new(*args, &block)
8
16
  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
17
  end
19
18
 
20
- attr_accessor :result
19
+ # instance methods
20
+ #
21
+ attr_accessor :map
21
22
 
22
23
  def initialize(*args, &block)
23
- @result = args.shift if args.first.is_a?(Result)
24
- super
25
- end
26
-
27
- def data
28
- result.data
24
+ @map = args.first.is_a?(Map) ? args.shift : Map.new
29
25
  end
30
26
 
31
27
  def errors
32
- result.errors
28
+ @map.errors
33
29
  end
34
30
 
35
- def ==(other)
36
- result == other.result
31
+ def path
32
+ @map.path
37
33
  end
38
34
 
35
+
36
+
37
+ # html generation methods
38
+ #
39
39
  def form(*args, &block)
40
40
  options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
41
41
  keys = args.flatten
@@ -87,9 +87,9 @@ module Dao
87
87
 
88
88
  value =
89
89
  if block.nil? and !options.has_key?(:value)
90
- value_for(data, keys)
90
+ value_for(@map, keys)
91
91
  else
92
- block ? block.call(data.get(keys)) : options.delete(:value)
92
+ block ? block.call(@map.get(keys)) : options.delete(:value)
93
93
  end
94
94
 
95
95
  input_(options_for(options, :type => type, :name => name, :value => value, :class => klass, :id => id, :data_error => error)){}
@@ -119,9 +119,9 @@ module Dao
119
119
 
120
120
  value =
121
121
  if block.nil? and !options.has_key?(:value)
122
- value_for(data, keys)
122
+ value_for(@map, keys)
123
123
  else
124
- block ? block.call(data.get(keys)) : options.delete(:value)
124
+ block ? block.call(@map.get(keys)) : options.delete(:value)
125
125
  end
126
126
 
127
127
  button_(options_for(options, :type => type, :name => name, :value => value, :class => klass, :id => id, :data_error => error)){}
@@ -145,9 +145,9 @@ module Dao
145
145
 
146
146
  value =
147
147
  if block.nil? and !options.has_key?(:value)
148
- value_for(data, keys)
148
+ value_for(@map, keys)
149
149
  else
150
- block ? block.call(data.get(keys)) : options.delete(:value)
150
+ block ? block.call(@map.get(keys)) : options.delete(:value)
151
151
  end
152
152
 
153
153
  textarea_(options_for(options, :name => name, :class => klass, :id => id, :data_error => error)){ value.to_s }
@@ -159,12 +159,13 @@ module Dao
159
159
 
160
160
  name = options.delete(:name) || name_for(keys)
161
161
  from = options.delete(:from) || options.delete(:options)
162
+ blank = options.delete(:blank)
162
163
 
163
164
  selected =
164
165
  if options.has_key?(:selected)
165
166
  options.delete(:selected)
166
167
  else
167
- value_for(data, keys)
168
+ value_for(@map, keys)
168
169
  end
169
170
 
170
171
  id = options.delete(:id) || id_for(keys)
@@ -176,7 +177,7 @@ module Dao
176
177
  if from.nil?
177
178
  key = keys.map{|key| "#{ key }"}
178
179
  key.last << "_options"
179
- from = data.get(*key) if data.has?(*key)
180
+ from = @map.get(*key) if @map.has?(*key)
180
181
  end
181
182
 
182
183
  list = Array(from)
@@ -190,6 +191,15 @@ module Dao
190
191
  list.map!{|element| [element, element]}
191
192
  end
192
193
 
194
+ case blank
195
+ when nil, false
196
+ nil
197
+ when true
198
+ list.push(nil)
199
+ else
200
+ list.unshift(blank)
201
+ end
202
+
193
203
  selected_value =
194
204
  case selected
195
205
  when Array
@@ -229,14 +239,16 @@ module Dao
229
239
  }
230
240
  end
231
241
 
242
+ # html generation support methods
243
+ #
232
244
  def id_for(keys)
233
- id = [result.path, keys.join('-')].compact.join('_')
245
+ id = [path, keys.join('-')].compact.join('_')
234
246
  slug_for(id)
235
247
  end
236
248
 
237
249
  def class_for(keys, klass = nil)
238
250
  klass =
239
- if result.errors.on?(keys)
251
+ if errors.on?(keys)
240
252
  [klass, 'dao', 'errors'].compact.join(' ')
241
253
  else
242
254
  [klass, 'dao'].compact.join(' ')
@@ -245,14 +257,12 @@ module Dao
245
257
  end
246
258
 
247
259
  def error_for(keys, klass = nil)
248
- if result.errors.on?(keys)
249
- result.errors.get(keys)
250
- end
260
+ errors.get(keys) if errors.on?(keys)
251
261
  end
252
262
 
253
- def value_for(data, keys)
254
- return nil unless data.has?(keys)
255
- value = Tagz.escapeHTML(data.get(keys))
263
+ def value_for(map, keys)
264
+ return nil unless map.has?(keys)
265
+ value = Tagz.escapeHTML(map.get(keys))
256
266
  end
257
267
 
258
268
  def Form.name_for(path, *keys)
@@ -270,9 +280,8 @@ module Dao
270
280
  params.keys.any?{|key| name_re =~ key.to_s}
271
281
  end
272
282
 
273
-
274
283
  def name_for(keys)
275
- Form.name_for(result.path, keys)
284
+ Form.name_for(path, keys)
276
285
  end
277
286
 
278
287
  def options_for(*hashes)
@@ -1,6 +1,6 @@
1
1
  module Dao
2
2
  class Interface
3
- Attrs = %w( api path method doc )
3
+ Attrs = %w( api path route method doc )
4
4
  Attrs.each{|attr| attr_accessor(attr)}
5
5
 
6
6
  def initialize(options = {})
@@ -1,41 +1,66 @@
1
1
  module Dao
2
2
  class Mode < ::String
3
+ # class methods
4
+ #
3
5
  class << Mode
4
6
  def for(mode)
5
- mode.is_a?(Mode) ? mode : Mode.new(mode.to_s)
7
+ return mode if mode.is_a?(Mode)
8
+ mode = mode.to_s
9
+ return Mode.send(mode) if Mode.respond_to?(mode)
10
+ Mode.new(mode)
6
11
  end
7
12
 
8
13
  def list
9
- List
14
+ @list ||= []
10
15
  end
11
16
 
12
- def default
13
- Mode.for(:read)
14
- end
15
- end
17
+ def add(mode)
18
+ mode = new(mode.to_s)
16
19
 
17
- Verbs = %w( options get head post put delete trace connect )
20
+ unless list.include?(mode)
21
+ list.push(mode)
22
+ singleton_class =
23
+ class << Mode
24
+ self
25
+ end
26
+ singleton_class.module_eval do
27
+ attr_accessor mode
28
+ end
29
+ Mode.send("#{ mode }=", mode)
30
+ mode
31
+ end
32
+ end
18
33
 
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)
34
+ def default
35
+ @default ||= Mode.for(:read)
24
36
  end
25
37
  end
26
38
 
27
- Read = Get unless defined?(Read)
28
- Write = Post unless defined?(Write)
39
+ # instance methods
40
+ #
41
+ def cases
42
+ @cases ||= []
43
+ end
29
44
 
30
- List = Verbs + %w( read write )
45
+ def case_of?(other)
46
+ self == other or other.cases.include?(self)
47
+ end
31
48
 
32
- List.each do |method|
33
- const = method.downcase.capitalize
34
- define_method(method){ const_get(const) }
49
+ def ===(other)
50
+ case_of?(other)
35
51
  end
36
52
 
37
- def ==(other)
38
- super(Mode.for(other))
53
+ Read = %w( options get head )
54
+ Write = %w( post put delete trace connect )
55
+ Http = Read + Write
56
+ Http.each do |verb|
57
+ Mode.add(verb)
39
58
  end
59
+
60
+ Mode.add(:read)
61
+ Read.each{|m| Mode.read.cases.push(Mode.send(m))}
62
+
63
+ Mode.add(:write)
64
+ Write.each{|m| Mode.write.cases.push(Mode.send(m))}
40
65
  end
41
66
  end