dao 2.0.0 → 2.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.
- data/README +96 -17
- data/Rakefile +92 -43
- data/dao.gemspec +12 -8
- data/lib/dao.rb +33 -20
- data/lib/dao/active_record.rb +51 -43
- data/lib/dao/api.rb +1 -1
- data/lib/dao/api/context.rb +6 -6
- data/lib/dao/api/dsl.rb +2 -2
- data/lib/dao/api/interfaces.rb +232 -0
- data/lib/dao/api/modes.rb +9 -6
- data/lib/dao/data.rb +7 -0
- data/lib/dao/errors.rb +27 -30
- data/lib/dao/form.rb +52 -28
- data/lib/dao/instance_exec.rb +37 -0
- data/lib/dao/interface.rb +16 -0
- data/lib/dao/params.rb +48 -24
- data/lib/dao/path.rb +1 -1
- data/lib/dao/rails.rb +5 -2
- data/lib/dao/rails/app/api.rb +1 -1
- data/lib/dao/rails/lib/generators/dao/dao_generator.rb +12 -0
- data/lib/dao/rails/lib/generators/dao/templates/api.rb +7 -1
- data/lib/dao/rails/lib/generators/dao/templates/api_controller.rb +25 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.css +27 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao.js +149 -0
- data/lib/dao/rails/lib/generators/dao/templates/dao_helper.rb +10 -0
- data/lib/dao/result.rb +53 -14
- data/lib/dao/status.rb +162 -1
- data/lib/dao/stdext.rb +6 -0
- data/lib/dao/support.rb +10 -2
- data/lib/dao/validations.rb +338 -14
- data/sample/rails_app/pubic/javascripts/dao.js +148 -0
- data/test/dao_test.rb +18 -19
- metadata +29 -18
- data/TODO +0 -37
- data/db/dao.yml +0 -8
@@ -0,0 +1,148 @@
|
|
1
|
+
if(!window.Dao){
|
2
|
+
(function(){
|
3
|
+
window.Dao = {};
|
4
|
+
|
5
|
+
// pull jQuery off the CDN iff needed
|
6
|
+
//
|
7
|
+
!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.4.2.js"%3E%3C/script%3E'));
|
8
|
+
var jq = jQuery;
|
9
|
+
|
10
|
+
// ctor
|
11
|
+
//
|
12
|
+
Dao.Api = function(){
|
13
|
+
this.route = '' + Dao.Api.route;
|
14
|
+
this.result = null;
|
15
|
+
this.results = [];
|
16
|
+
this.mode = 'get';
|
17
|
+
this.method = Dao[this.mode];
|
18
|
+
};
|
19
|
+
Dao.Api.route = '/api';
|
20
|
+
Dao.Api.modes = ["options", "get", "head", "post", "put", "delete", "trace", "connect"];
|
21
|
+
|
22
|
+
// single call interface
|
23
|
+
//
|
24
|
+
Dao.Api.prototype.call = function(){
|
25
|
+
var api = this;
|
26
|
+
var options = {};
|
27
|
+
|
28
|
+
if(arguments.length == 1){
|
29
|
+
var arg = arguments[0];
|
30
|
+
|
31
|
+
if(typeof(arg)=='string'){
|
32
|
+
options.path = arg;
|
33
|
+
} else {
|
34
|
+
options = arg;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
if(arguments.length > 1){
|
39
|
+
options.path = arguments[0];
|
40
|
+
options.params = arguments[1];
|
41
|
+
options.success = arguments[2];
|
42
|
+
}
|
43
|
+
|
44
|
+
if(!options.path){
|
45
|
+
options.path = '/ping';
|
46
|
+
}
|
47
|
+
|
48
|
+
if(!options.params){
|
49
|
+
options.params = {};
|
50
|
+
}
|
51
|
+
|
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
|
+
var url = api.route + options.path;
|
61
|
+
|
62
|
+
var data = options.params;
|
63
|
+
|
64
|
+
var success = function(result){
|
65
|
+
var result = new Dao.Result(result);
|
66
|
+
if(options.success){
|
67
|
+
options.success(result);
|
68
|
+
} else {
|
69
|
+
api.result = result;
|
70
|
+
api.results.push(result);
|
71
|
+
}
|
72
|
+
};
|
73
|
+
|
74
|
+
var ajax = {};
|
75
|
+
ajax.url = url;
|
76
|
+
ajax.data = data;
|
77
|
+
ajax.success = success;
|
78
|
+
|
79
|
+
Dao[api.mode](ajax);
|
80
|
+
return(api);
|
81
|
+
};
|
82
|
+
|
83
|
+
// meta-program api.read(..), api.post(...), ...
|
84
|
+
//
|
85
|
+
for(var i = 0; i < Dao.Api.modes.length; i++){
|
86
|
+
(function(){
|
87
|
+
var mode = Dao.Api.modes[i];
|
88
|
+
|
89
|
+
Dao.Api.prototype[mode] = function(){
|
90
|
+
var api = this;
|
91
|
+
var previous = api.mode;
|
92
|
+
api.mode = mode;
|
93
|
+
var returned = api.call.apply(api, arguments);
|
94
|
+
api.mode = previous;
|
95
|
+
return(returned);
|
96
|
+
};
|
97
|
+
})();
|
98
|
+
}
|
99
|
+
Dao.Api.prototype['read'] = Dao.Api.prototype['get'];
|
100
|
+
Dao.Api.prototype['write'] = Dao.Api.prototype['post'];
|
101
|
+
|
102
|
+
// a thin wrapper on results for now. TODO - make it smarter
|
103
|
+
//
|
104
|
+
Dao.Result = function(options){
|
105
|
+
this.path = options.path;
|
106
|
+
this.status = options.status;
|
107
|
+
this.errors = options.errors;
|
108
|
+
this.data = options.data;
|
109
|
+
|
110
|
+
//parts = ('' + this.status).split(/\s+/);
|
111
|
+
//this.status.code = parseInt(parts.shift());
|
112
|
+
//this.status.message = parts.join(' ');
|
113
|
+
};
|
114
|
+
|
115
|
+
// ajax utils
|
116
|
+
//
|
117
|
+
Dao.ajax = function(options){
|
118
|
+
var ajax = {};
|
119
|
+
ajax.type = options.type;
|
120
|
+
ajax.url = options.url;
|
121
|
+
ajax.dataType = 'json';
|
122
|
+
if(ajax.type == 'POST' || ajax.type == 'PUT'){
|
123
|
+
ajax.data = jq.toJSON(options.data || {});
|
124
|
+
} else {
|
125
|
+
ajax.data = (options.data || {});
|
126
|
+
};
|
127
|
+
ajax.contentType = (options.contentType || 'application/json; charset=utf-8');
|
128
|
+
ajax.success = (options.success || function(){});
|
129
|
+
jq.ajax(ajax);
|
130
|
+
};
|
131
|
+
|
132
|
+
// meta-program Api.get(...), Api.post(...)
|
133
|
+
//
|
134
|
+
for(var i = 0; i < Dao.Api.modes.length; i++){
|
135
|
+
(function(){
|
136
|
+
var mode = Dao.Api.modes[i];
|
137
|
+
|
138
|
+
Dao[mode] = function(options){
|
139
|
+
options.type = mode.toUpperCase();
|
140
|
+
Dao.ajax(options);
|
141
|
+
};
|
142
|
+
})();
|
143
|
+
}
|
144
|
+
|
145
|
+
Dao.api = new Dao.Api();
|
146
|
+
window.api = window.api || Dao.api;
|
147
|
+
}());
|
148
|
+
}
|
data/test/dao_test.rb
CHANGED
@@ -19,13 +19,13 @@ Testing Dao do
|
|
19
19
|
}
|
20
20
|
end
|
21
21
|
|
22
|
-
testing 'that apis can have callable
|
22
|
+
testing 'that apis can have callable interfaces added to them which accept params and return results' do
|
23
23
|
captured = []
|
24
24
|
|
25
25
|
api_class =
|
26
26
|
assert{
|
27
27
|
Dao.api do
|
28
|
-
|
28
|
+
interface(:foo) do |params, result|
|
29
29
|
captured.push(params, result)
|
30
30
|
end
|
31
31
|
end
|
@@ -35,20 +35,20 @@ Testing Dao do
|
|
35
35
|
assert{ result.is_a?(Hash) }
|
36
36
|
end
|
37
37
|
|
38
|
-
testing 'that
|
38
|
+
testing 'that interfaces are automatically called according to arity' do
|
39
39
|
api = assert{ Class.new(Dao.api) }
|
40
|
-
assert{ api.class_eval{
|
41
|
-
assert{ api.class_eval{
|
42
|
-
assert{ api.class_eval{
|
40
|
+
assert{ api.class_eval{ interface(:zero){|| result.update :args => [] } } }
|
41
|
+
assert{ api.class_eval{ interface(:one){|a| result.update :args => [a]} } }
|
42
|
+
assert{ api.class_eval{ interface(:two){|a,b| result.update :args => [a,b]} } }
|
43
43
|
|
44
44
|
assert{ api.new.call(:zero).args.size == 0 }
|
45
45
|
assert{ api.new.call(:one).args.size == 1 }
|
46
46
|
assert{ api.new.call(:two).args.size == 2 }
|
47
47
|
end
|
48
48
|
|
49
|
-
testing 'that
|
49
|
+
testing 'that interfaces have an auto-vivifying params/result' do
|
50
50
|
api = assert{ Class.new(Dao.api) }
|
51
|
-
assert{ api.class_eval{
|
51
|
+
assert{ api.class_eval{ interface(:foo){ params; result; } } }
|
52
52
|
result = assert{ api.new.call(:foo) }
|
53
53
|
assert{ result.path.to_s =~ /foo/ }
|
54
54
|
end
|
@@ -136,7 +136,7 @@ Testing Dao do
|
|
136
136
|
assert{
|
137
137
|
api_class =
|
138
138
|
Dao.api do
|
139
|
-
|
139
|
+
interface('/foobar'){
|
140
140
|
data.update(params)
|
141
141
|
}
|
142
142
|
end
|
@@ -185,7 +185,7 @@ Testing Dao do
|
|
185
185
|
testing 'that simple validations work' do
|
186
186
|
result = Dao::Result.new
|
187
187
|
assert{ result.validates(:password){|password| password=='haxor'} }
|
188
|
-
result.
|
188
|
+
result.data.set(:password, 'haxor')
|
189
189
|
assert{ result.valid? }
|
190
190
|
end
|
191
191
|
|
@@ -193,7 +193,7 @@ Testing Dao do
|
|
193
193
|
assert{
|
194
194
|
api_class =
|
195
195
|
Dao.api do
|
196
|
-
|
196
|
+
interface('/foobar'){
|
197
197
|
result.validates(:a)
|
198
198
|
params.validate(:b)
|
199
199
|
validates(:c)
|
@@ -209,19 +209,18 @@ Testing Dao do
|
|
209
209
|
#
|
210
210
|
testing 'that validations can be cleared and do not clobber manually added errors' do
|
211
211
|
result = Dao::Result.new
|
212
|
-
|
213
|
-
params = result.params
|
212
|
+
data = result.data
|
214
213
|
errors = result.errors
|
215
214
|
|
216
215
|
assert{ result.validates(:email){|email| email.to_s.split(/@/).size == 2} }
|
217
|
-
assert{ result.validates(:password){|password| password == '
|
216
|
+
assert{ result.validates(:password){|password| password == 'pa$$w0rd'} }
|
218
217
|
|
219
|
-
|
220
|
-
assert{ not result.valid? }
|
221
|
-
|
222
|
-
params.set(:password => 'haxor')
|
218
|
+
data.set(:email => 'ara@dojo4.com', :password => 'pa$$w0rd')
|
223
219
|
assert{ result.valid? }
|
224
220
|
|
221
|
+
data.set(:password => 'haxor')
|
222
|
+
assert{ !result.valid? }
|
223
|
+
|
225
224
|
errors.add(:name, 'ara')
|
226
225
|
assert{ not result.valid? }
|
227
226
|
end
|
@@ -234,7 +233,7 @@ Testing Dao do
|
|
234
233
|
Dao.api {
|
235
234
|
description 'foobar'
|
236
235
|
doc 'signature' => {'read' => '...', 'write' => '...'}
|
237
|
-
|
236
|
+
interface('/barfoo'){}
|
238
237
|
}
|
239
238
|
}
|
240
239
|
api_class_index = assert{ api_class.index.is_a?(Hash) }
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dao
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 2.0.0
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ara T. Howard
|
@@ -15,35 +15,39 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-22 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
|
-
name:
|
22
|
+
name: tagz
|
23
23
|
prerelease: false
|
24
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ~>
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
hash:
|
29
|
+
hash: 87
|
30
30
|
segments:
|
31
|
+
- 8
|
32
|
+
- 2
|
31
33
|
- 0
|
32
|
-
version:
|
34
|
+
version: 8.2.0
|
33
35
|
type: :runtime
|
34
36
|
version_requirements: *id001
|
35
37
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
38
|
+
name: map
|
37
39
|
prerelease: false
|
38
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
41
|
none: false
|
40
42
|
requirements:
|
41
|
-
- -
|
43
|
+
- - ~>
|
42
44
|
- !ruby/object:Gem::Version
|
43
|
-
hash:
|
45
|
+
hash: 21
|
44
46
|
segments:
|
45
|
-
-
|
46
|
-
|
47
|
+
- 2
|
48
|
+
- 6
|
49
|
+
- 1
|
50
|
+
version: 2.6.1
|
47
51
|
type: :runtime
|
48
52
|
version_requirements: *id002
|
49
53
|
- !ruby/object:Gem::Dependency
|
@@ -52,12 +56,14 @@ dependencies:
|
|
52
56
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
57
|
none: false
|
54
58
|
requirements:
|
55
|
-
- -
|
59
|
+
- - ~>
|
56
60
|
- !ruby/object:Gem::Version
|
57
|
-
hash:
|
61
|
+
hash: 17
|
58
62
|
segments:
|
59
63
|
- 0
|
60
|
-
|
64
|
+
- 7
|
65
|
+
- 9
|
66
|
+
version: 0.7.9
|
61
67
|
type: :runtime
|
62
68
|
version_requirements: *id003
|
63
69
|
description: "description: dao kicks the ass"
|
@@ -70,12 +76,12 @@ extra_rdoc_files: []
|
|
70
76
|
|
71
77
|
files:
|
72
78
|
- dao.gemspec
|
73
|
-
- db/dao.yml
|
74
79
|
- lib/dao/active_record.rb
|
75
80
|
- lib/dao/api/context.rb
|
76
81
|
- lib/dao/api/dsl.rb
|
77
82
|
- lib/dao/api/endpoints.rb
|
78
83
|
- lib/dao/api/initializers.rb
|
84
|
+
- lib/dao/api/interfaces.rb
|
79
85
|
- lib/dao/api/modes.rb
|
80
86
|
- lib/dao/api.rb
|
81
87
|
- lib/dao/blankslate.rb
|
@@ -86,6 +92,8 @@ files:
|
|
86
92
|
- lib/dao/errors.rb
|
87
93
|
- lib/dao/exceptions.rb
|
88
94
|
- lib/dao/form.rb
|
95
|
+
- lib/dao/instance_exec.rb
|
96
|
+
- lib/dao/interface.rb
|
89
97
|
- lib/dao/mode.rb
|
90
98
|
- lib/dao/mongo_mapper.rb
|
91
99
|
- lib/dao/params.rb
|
@@ -96,6 +104,9 @@ files:
|
|
96
104
|
- lib/dao/rails/lib/generators/dao/dao_generator.rb
|
97
105
|
- lib/dao/rails/lib/generators/dao/templates/api.rb
|
98
106
|
- lib/dao/rails/lib/generators/dao/templates/api_controller.rb
|
107
|
+
- lib/dao/rails/lib/generators/dao/templates/dao.css
|
108
|
+
- lib/dao/rails/lib/generators/dao/templates/dao.js
|
109
|
+
- lib/dao/rails/lib/generators/dao/templates/dao_helper.rb
|
99
110
|
- lib/dao/rails/lib/generators/dao/USAGE
|
100
111
|
- lib/dao/rails.rb
|
101
112
|
- lib/dao/result.rb
|
@@ -136,6 +147,7 @@ files:
|
|
136
147
|
- sample/rails_app/log/production.log
|
137
148
|
- sample/rails_app/log/server.log
|
138
149
|
- sample/rails_app/log/test.log
|
150
|
+
- sample/rails_app/pubic/javascripts/dao.js
|
139
151
|
- sample/rails_app/public/404.html
|
140
152
|
- sample/rails_app/public/422.html
|
141
153
|
- sample/rails_app/public/500.html
|
@@ -157,7 +169,6 @@ files:
|
|
157
169
|
- test/dao_test.rb
|
158
170
|
- test/helper.rb
|
159
171
|
- test/testing.rb
|
160
|
-
- TODO
|
161
172
|
has_rdoc: true
|
162
173
|
homepage: http://github.com/ahoward/dao
|
163
174
|
licenses: []
|
data/TODO
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
todo:
|
2
|
-
|
3
|
-
route -> path??
|
4
|
-
|
5
|
-
- nested AR conversions
|
6
|
-
to_dao(:a, :b => [:foo, :bar])
|
7
|
-
|
8
|
-
- AR as_dao contains the model type/class.name
|
9
|
-
|
10
|
-
|
11
|
-
done:
|
12
|
-
- engine-ify the rails stuff? or what
|
13
|
-
- generator api
|
14
|
-
- controller
|
15
|
-
- helper
|
16
|
-
- json/pretty fix baked in? (yajl might simply this...)
|
17
|
-
- description/doc logic
|
18
|
-
- api.index
|
19
|
-
- to_alpo -> to_dao
|
20
|
-
- tests!
|
21
|
-
- #call auto parses data iff appropriate
|
22
|
-
@result = api.read.call('/posts/new(', params) ### check keys for '/posts/new'
|
23
|
-
- re-visit how parameters are parsed, perhaps we just use rack?
|
24
|
-
- next 'data' => {}
|
25
|
-
- check the db layer
|
26
|
-
- make sure one can call route based method (/foo/:bar) methods with params...
|
27
|
-
- Path==Route ??
|
28
|
-
- add result.rb, params.rb
|
29
|
-
- name -> path
|
30
|
-
- tagz for html methods?
|
31
|
-
- data aquires the name/path of the method?
|
32
|
-
- endpoints are objects that respond to call. namespaces respond to call.
|
33
|
-
api responds to call
|
34
|
-
- nested namespaces
|
35
|
-
- routing for path_info + mode
|
36
|
-
route(path_info, :mode => mode, :params => params)
|
37
|
-
- call() on namespaces AND endpoints... why?
|