dao 2.1.0 → 2.2.3

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.
@@ -24,7 +24,7 @@ Api =
24
24
  end
25
25
 
26
26
  def user_for(arg)
27
- User.find(arg)
27
+ User.respond_to?(:for) ? User.for(arg) : User.find(arg)
28
28
  end
29
29
 
30
30
  alias_method('user', 'effective_user')
@@ -1,52 +1,39 @@
1
1
  class APIController < ApplicationController
2
2
  layout false
3
3
 
4
- skip_before_filter true
5
4
  skip_before_filter :verify_authenticity_token
6
5
 
7
6
  before_filter :setup_path
8
7
  before_filter :setup_api
9
8
 
10
- WhiteList = %w( ping index module )
11
-
12
- ### skip_before_filter :set_current_user if Rails.env.production?
13
-
14
- ##
15
- # /api/foo/2/bar/4 -> api.call('/foo/2/bar/4')
16
- #
17
- def call
18
- path = params[:path]
19
- mode = params['mode'] || (request.get? ? 'read' : 'write')
20
-
21
- result = api.mode(mode).call(path, params)
9
+ WhiteList = Set.new( %w( ping index ) )
10
+ BlackList = Set.new( %w( ) )
22
11
 
12
+ def index
13
+ result = call(path, params)
23
14
  respond_with(result)
24
15
  end
25
16
 
26
- ##
27
- #
28
- def index
29
- json = json_for(api.index)
17
+ protected
30
18
 
31
- respond_to do |wants|
32
- wants.json{ render(:json => json) }
33
- wants.html{ render(:text => json, :content_type => 'text/plain') }
34
- end
19
+ def call(path, params)
20
+ mode = params['mode'] || (request.get? ? 'read' : 'write')
21
+ result = api.mode(mode).call(path, params)
35
22
  end
36
23
 
37
- protected
24
+ def respond_with(object, options = {})
25
+ json = json_for(object)
38
26
 
39
- def respond_with(result)
40
- json = json_for(result)
27
+ status = object.status if object.respond_to?(:status)
28
+ status = status.code if status.respond_to?(:code)
29
+ status = options[:status] || 200 unless status
41
30
 
42
31
  respond_to do |wants|
43
- wants.json{ render :json => json, :status => result.status.code }
44
- wants.html{ render :text => json, :status => result.status.code, :content_type => 'text/plain' }
32
+ wants.json{ render :json => json, :status => status }
33
+ wants.html{ render :text => json, :status => status, :content_type => 'text/plain' }
45
34
  end
46
35
  end
47
36
 
48
- # if you don't have yajl-ruby and yajl/json_gem loaded your json will suck
49
- #
50
37
  def json_for(object)
51
38
  if Rails.env.production?
52
39
  ::JSON.generate(object)
@@ -56,7 +43,7 @@ protected
56
43
  end
57
44
 
58
45
  def setup_path
59
- @path = params[:path]
46
+ @path = params[:path] || params[:action] || 'index'
60
47
  end
61
48
 
62
49
  def path
@@ -97,14 +84,21 @@ protected
97
84
  end
98
85
 
99
86
  def self.white_listed?(path)
100
- @white_listed ||= ( WhiteList.inject(Hash.new){|hash, path| hash.update(path.to_s => true)} )
101
- @white_listed[path.to_s]
87
+ WhiteList.include?(path.to_s)
102
88
  end
103
89
 
104
90
  def white_listed?(path)
105
91
  self.class.white_listed?(path)
106
92
  end
107
93
 
94
+ def self.black_listed?(path)
95
+ BlackList.include?(path.to_s)
96
+ end
97
+
98
+ def black_listed?(path)
99
+ self.class.black_listed?(path)
100
+ end
101
+
108
102
  def http_basic_auth
109
103
  @http_basic_auth ||= (
110
104
  request.env['HTTP_AUTHORIZATION'] ||
@@ -37,8 +37,14 @@ if(!window.Dao){
37
37
 
38
38
  if(arguments.length > 1){
39
39
  options.path = arguments[0];
40
- options.params = arguments[1];
41
- options.success = arguments[2];
40
+
41
+ if(typeof(arguments[1])=='function'){
42
+ options.success = arguments[1];
43
+ options.params = arguments[2];
44
+ } else {
45
+ options.params = arguments[1];
46
+ options.success = arguments[2];
47
+ }
42
48
  }
43
49
 
44
50
  if(!options.path){
@@ -49,35 +55,35 @@ if(!window.Dao){
49
55
  options.params = {};
50
56
  }
51
57
 
52
- if(!options.success){
53
- options.success = function(result){
54
- result = new Dao.Result(result);
55
- api.result = result;
56
- api.results.push(result);
57
- };
58
- }
59
-
60
58
  var url = api.route + options.path;
61
-
62
59
  var data = options.params;
63
60
 
64
- var success = function(result){
65
- var result = new Dao.Result(result);
66
- if(options.success){
61
+ if(options.success){
62
+
63
+ var returned = api;
64
+ var success = function(result){
65
+ var result = new Dao.Result(result);
67
66
  options.success(result);
68
- } else {
69
- api.result = result;
70
- api.results.push(result);
71
- }
72
- };
67
+ };
73
68
 
74
- var ajax = {};
75
- ajax.url = url;
76
- ajax.data = data;
77
- ajax.success = success;
69
+ var ajax = {'url' : url, 'data' : data, 'success' : success, 'async' : true};
70
+
71
+ Dao[api.mode](ajax);
72
+ return(returned);
78
73
 
79
- Dao[api.mode](ajax);
80
- return(api);
74
+ } else {
75
+
76
+ var returned = null;
77
+ var success = function(result){
78
+ returned = new Dao.Result(result);
79
+ };
80
+
81
+ var ajax = {'url' : url, 'data' : data, 'success' : success, 'async' : false};
82
+
83
+ Dao[api.mode](ajax);
84
+ return(returned);
85
+
86
+ };
81
87
  };
82
88
 
83
89
  // meta-program api.read(..), api.post(...), ...
@@ -120,6 +126,9 @@ if(!window.Dao){
120
126
  ajax.url = options.url;
121
127
  ajax.dataType = 'json';
122
128
  ajax.cache = false;
129
+ if(options.async==false || options.sync==true){
130
+ ajax.async = false;
131
+ };
123
132
  if(ajax.type == 'POST' || ajax.type == 'PUT'){
124
133
  ajax.data = jq.toJSON(options.data || {});
125
134
  } else {
@@ -1,9 +1,10 @@
1
1
  module DaoHelper
2
2
  def render_dao(result, *args, &block)
3
3
  if result.status =~ 200 or result.status == 420
4
+ @result = result unless defined?(@result)
4
5
  render(*args, &block)
5
6
  else
6
- render(:text => result.status, :status => result.status.code)
7
+ result.error!
7
8
  end
8
9
  end
9
10
  end
data/lib/dao/result.rb CHANGED
@@ -7,6 +7,7 @@ module Dao
7
7
  attr_accessor :mode
8
8
  attr_accessor :params
9
9
  attr_accessor :validations
10
+ attr_accessor :presenter
10
11
  attr_accessor :form
11
12
  attr_accessor :forcing_validity
12
13
 
@@ -18,11 +19,19 @@ module Dao
18
19
  options = Dao.options_for!(args)
19
20
  args.push('/dao') if args.empty?
20
21
 
21
- path = Path.for(*args)
22
+ path_args = args.select{|arg| arg.is_a?(String) or args.is_a?(Symbol)}
23
+ data_args = args.select{|arg| arg.is_a?(Hash)}
24
+ data_args += [options[:data]] if options.has_key?(:data)
25
+
26
+ path = Path.for(*path_args)
22
27
  status = Status.ok
23
28
  errors = Errors.new
24
29
  data = Data.new
25
30
 
31
+ data_args.each do |data_arg|
32
+ data.update(data_arg)
33
+ end
34
+
26
35
  api = options[:api]
27
36
  interface = options[:interface]
28
37
  params = options[:params] || Params.new
@@ -33,6 +42,7 @@ module Dao
33
42
 
34
43
  form = Form.for(self)
35
44
  validations = Validations.for(self)
45
+ presenter = Presenter.for(self)
36
46
 
37
47
  self[:path] = path
38
48
  self[:status] = status
@@ -45,6 +55,7 @@ module Dao
45
55
  @params = params
46
56
  @form = form
47
57
  @validations = validations
58
+ @presenter = presenter
48
59
  @forcing_validity = false
49
60
  end
50
61
 
@@ -90,11 +101,13 @@ module Dao
90
101
  @forcing_validity = true
91
102
  end
92
103
 
93
- def valid?
104
+ def valid?(*args)
94
105
  if @forcing_validity
95
106
  true
96
107
  else
108
+ options = Dao.options_for!(args)
97
109
  validate unless validations.ran?
110
+ validate if options[:validate]
98
111
  errors.empty? and status.ok?
99
112
  end
100
113
  end
@@ -122,5 +135,17 @@ module Dao
122
135
  def validates(*args, &block)
123
136
  validations.add(*args, &block)
124
137
  end
138
+
139
+ def error!
140
+ raise Dao::Error::Result.for(self)
141
+ end
142
+
143
+ def tag(*args, &block)
144
+ presenter.tag(*args, &block)
145
+ end
146
+
147
+ def inspect
148
+ ::JSON.pretty_generate(self, :max_nesting => 0)
149
+ end
125
150
  end
126
151
  end
data/lib/dao/status.rb CHANGED
@@ -113,6 +113,10 @@ module Dao
113
113
  Groups.each do |code, group|
114
114
  module_eval <<-__, __FILE__, __LINE__ -1
115
115
 
116
+ def Status.#{ group }
117
+ @status_group_#{ group } ||= Status.for(#{ code })
118
+ end
119
+
116
120
  def #{ group }?()
117
121
  #{ code } == @group
118
122
  end
@@ -183,8 +187,12 @@ module Dao
183
187
  message = Code2Message[code]
184
188
  new(code, message)
185
189
  when Symbol, String
186
- sym = Status.underscore(arg).to_sym
187
- code = Symbol2Code[sym]
190
+ if arg.to_s =~ %r/^\d+$/
191
+ code = arg.to_i
192
+ else
193
+ sym = Status.underscore(arg).to_sym
194
+ code = Symbol2Code[sym]
195
+ end
188
196
  if code
189
197
  message = Code2Message[code]
190
198
  else
data/lib/dao/support.rb CHANGED
@@ -65,6 +65,6 @@ module Dao
65
65
  end
66
66
 
67
67
  def name_for(path, *keys)
68
- "#{ path }(#{ Array(keys).flatten.compact.join(',') })"
68
+ Form.name_for(path, *keys)
69
69
  end
70
70
  end
@@ -28,6 +28,8 @@ module Dao
28
28
  end
29
29
 
30
30
 
31
+ # class methods
32
+ #
31
33
  class << Validations
32
34
  def for(*args, &block)
33
35
  new(*args, &block)
@@ -43,6 +45,8 @@ module Dao
43
45
  end
44
46
  end
45
47
 
48
+ # instance methods
49
+ #
46
50
  attr_accessor :result
47
51
  attr_accessor :ran
48
52
 
@@ -51,7 +55,6 @@ module Dao
51
55
  @ran = false
52
56
  super
53
57
  end
54
-
55
58
  alias_method('ran?', 'ran')
56
59
 
57
60
  def params
@@ -75,11 +78,10 @@ module Dao
75
78
  depth_first_each{ size += 1 }
76
79
  size
77
80
  end
78
-
79
81
  alias_method('count', 'size')
80
82
  alias_method('length', 'size')
81
83
 
82
- Cleared = '___CLEARED___'.freeze unless defined?(Cleared)
84
+ Cleared = 'Cleared'.freeze unless defined?(Cleared)
83
85
 
84
86
  def run
85
87
  previous_errors = []
@@ -88,8 +90,7 @@ module Dao
88
90
  errors.each_message do |keys, message|
89
91
  previous_errors.push([keys, message])
90
92
  end
91
-
92
- errors.clear
93
+ errors.clear!
93
94
 
94
95
  depth_first_each do |keys, chain|
95
96
  chain.each do |callback|
@@ -158,12 +159,10 @@ module Dao
158
159
  options = Dao.map_for(args.last.is_a?(Hash) ? args.pop : {})
159
160
  block = args.pop if args.last.respond_to?(:call)
160
161
  block ||= NotNil
161
- callback = Validations::Callback.new(options, &block)
162
+ callback = Callback.new(options, &block)
162
163
  set(args => Callback::Chain.new) unless has?(args)
163
164
  get(args).add(callback)
164
165
  callback
165
- #args.push(callback)
166
- #set(*args)
167
166
  end
168
167
  end
169
168
 
@@ -429,6 +428,142 @@ module Dao
429
428
 
430
429
  validates(*args, &block)
431
430
  end
431
+
432
+ def validates_any_of(*args)
433
+ options = Dao.options_for!(args)
434
+ list = args
435
+
436
+ list.each do |args|
437
+ candidates = list.dup
438
+ candidates.delete(args)
439
+
440
+ message = options[:message] || "(or #{ candidates.map{|candidate| Array(candidate).join('.')}.join(', ') } ) is blank or missing"
441
+ allow_nil = options[:allow_nil]
442
+ allow_blank = options[:allow_blank]
443
+
444
+ result = self.result
445
+
446
+ block =
447
+ lambda do |value|
448
+ map = Dao.map(:valid => true)
449
+ values = list.map{|key| result.get(key)}
450
+ valid = false
451
+ values.each do |val|
452
+ if val
453
+ valid = true
454
+ break
455
+ end
456
+
457
+ if val.nil?
458
+ if allow_nil
459
+ valid = true
460
+ break
461
+ end
462
+ end
463
+
464
+ val = val.to_s.strip
465
+
466
+ if val.empty?
467
+ if allow_blank
468
+ valid = true
469
+ break
470
+ end
471
+ end
472
+ end
473
+
474
+ unless valid
475
+ if value.nil?
476
+ unless allow_nil
477
+ map[:message] = message
478
+ map[:valid] = false
479
+ throw(:valid, map)
480
+ end
481
+ end
482
+
483
+ value = value.to_s.strip
484
+
485
+ if value.empty?
486
+ unless allow_blank
487
+ map[:message] = message
488
+ map[:valid] = false
489
+ throw(:valid, map)
490
+ end
491
+ end
492
+ end
493
+
494
+ map
495
+ end
496
+ validates(*args, &block)
497
+ end
498
+ end
499
+
500
+ def validates_all_of(*args)
501
+ options = Dao.options_for!(args)
502
+ list = args
503
+
504
+ list.each do |args|
505
+ candidates = list.dup
506
+ candidates.delete(args)
507
+
508
+ message = options[:message] || "(and #{ candidates.map{|candidate| Array(candidate).join('.')}.join(', ') } ) is blank or missing"
509
+ allow_nil = options[:allow_nil]
510
+ allow_blank = options[:allow_blank]
511
+
512
+ result = self.result
513
+
514
+ block =
515
+ lambda do |value|
516
+ map = Dao.map(:valid => true)
517
+
518
+ values = list.map{|key| result.get(key)}
519
+ valid = true
520
+ values.each do |val|
521
+ if val
522
+ break
523
+ end
524
+
525
+ if val.nil?
526
+ unless allow_nil
527
+ valid = false
528
+ break
529
+ end
530
+ end
531
+
532
+ val = val.to_s.strip
533
+
534
+ if val.empty?
535
+ unless allow_blank
536
+ valid = false
537
+ break
538
+ end
539
+ end
540
+ end
541
+
542
+ unless valid
543
+ if value.nil?
544
+ unless allow_nil
545
+ map[:message] = message
546
+ map[:valid] = false
547
+ throw(:valid, map)
548
+ end
549
+ end
550
+
551
+ value = value.to_s.strip
552
+
553
+ if value.empty?
554
+ unless allow_blank
555
+ map[:message] = message
556
+ map[:valid] = false
557
+ throw(:valid, map)
558
+ end
559
+ end
560
+ end
561
+
562
+ map
563
+ end
564
+ validates(*args, &block)
565
+ end
566
+ end
432
567
  end
433
568
 
434
569
  def Validations.add(method_name, &block)