dao 2.1.0 → 2.2.3

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