fauna 0.1.2 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/Manifest +2 -4
- data/README.md +20 -24
- data/fauna.gemspec +5 -5
- data/lib/fauna.rb +20 -22
- data/lib/fauna/client.rb +1 -1
- data/lib/fauna/connection.rb +19 -8
- data/lib/fauna/ddl.rb +27 -30
- data/lib/fauna/model.rb +8 -5
- data/lib/fauna/model/class.rb +7 -18
- data/lib/fauna/model/{timeline.rb → event_set.rb} +16 -17
- data/lib/fauna/model/user.rb +4 -19
- data/lib/fauna/resource.rb +15 -51
- data/test/fixtures.rb +3 -2
- data/test/model/association_test.rb +1 -1
- data/test/model/class_test.rb +2 -1
- data/test/model/{timeline_test.rb → event_set_test.rb} +4 -16
- data/test/model/user_test.rb +7 -12
- data/test/model/validation_test.rb +1 -11
- metadata +6 -10
- data/lib/fauna/model/follow.rb +0 -43
- data/test/model/follow_test.rb +0 -47
data/CHANGELOG
CHANGED
data/Manifest
CHANGED
@@ -11,9 +11,8 @@ lib/fauna/connection.rb
|
|
11
11
|
lib/fauna/ddl.rb
|
12
12
|
lib/fauna/model.rb
|
13
13
|
lib/fauna/model/class.rb
|
14
|
-
lib/fauna/model/
|
14
|
+
lib/fauna/model/event_set.rb
|
15
15
|
lib/fauna/model/publisher.rb
|
16
|
-
lib/fauna/model/timeline.rb
|
17
16
|
lib/fauna/model/user.rb
|
18
17
|
lib/fauna/rails.rb
|
19
18
|
lib/fauna/resource.rb
|
@@ -22,9 +21,8 @@ test/connection_test.rb
|
|
22
21
|
test/fixtures.rb
|
23
22
|
test/model/association_test.rb
|
24
23
|
test/model/class_test.rb
|
25
|
-
test/model/
|
24
|
+
test/model/event_set_test.rb
|
26
25
|
test/model/publisher_test.rb
|
27
|
-
test/model/timeline_test.rb
|
28
26
|
test/model/user_test.rb
|
29
27
|
test/model/validation_test.rb
|
30
28
|
test/readme_test.rb
|
data/README.md
CHANGED
@@ -54,8 +54,9 @@ debugging:
|
|
54
54
|
|
55
55
|
```ruby
|
56
56
|
require "logger"
|
57
|
-
$fauna = Fauna::Connection.new(
|
58
|
-
|
57
|
+
$fauna = Fauna::Connection.new(
|
58
|
+
publisher_key: publisher_key,
|
59
|
+
logger: Logger.new(STDERR))
|
59
60
|
```
|
60
61
|
|
61
62
|
### Client Contexts
|
@@ -65,7 +66,8 @@ context*, and then manipulate resources within that context:
|
|
65
66
|
|
66
67
|
```ruby
|
67
68
|
Fauna::Client.context($fauna) do
|
68
|
-
user = Fauna::User.create!(
|
69
|
+
user = Fauna::User.create!(email: "taran@example.com")
|
70
|
+
user.data["name"] = "Taran"
|
69
71
|
user.data["profession"] = "Pigkeeper"
|
70
72
|
user.save!
|
71
73
|
user.destroy
|
@@ -89,25 +91,20 @@ fields:
|
|
89
91
|
|
90
92
|
```ruby
|
91
93
|
Fauna::Client.context($fauna) do
|
92
|
-
user = Fauna::User.create(
|
94
|
+
user = Fauna::User.create(unique_id: "taran77")
|
93
95
|
|
94
96
|
# fields
|
95
|
-
user.ref
|
96
|
-
user.ts
|
97
|
-
user.deleted
|
98
|
-
user.
|
97
|
+
user.ref # => "users/123"
|
98
|
+
user.ts # => 1359579766996758
|
99
|
+
user.deleted # => false
|
100
|
+
user.unique_id # => "taran77"
|
99
101
|
|
100
102
|
# data and references
|
101
103
|
user.data # => {}
|
102
104
|
user.references # => {}
|
103
105
|
|
104
|
-
#
|
106
|
+
# changes event set
|
105
107
|
user.changes
|
106
|
-
user.user_follows
|
107
|
-
user.user_followers
|
108
|
-
user.instance_follows
|
109
|
-
user.instance_followers
|
110
|
-
user.local
|
111
108
|
end
|
112
109
|
```
|
113
110
|
|
@@ -158,15 +155,15 @@ end
|
|
158
155
|
```
|
159
156
|
|
160
157
|
Fields and references can be configured dynamically, but the classes
|
161
|
-
and
|
158
|
+
and event sets themselves must be configured with an additional
|
162
159
|
`Fauna.schema` block (normally placed in
|
163
160
|
`config/initializers/fauna.rb`):
|
164
161
|
|
165
162
|
```ruby
|
166
163
|
Fauna.schema do
|
167
164
|
with Pig do
|
168
|
-
# Add a custom
|
169
|
-
|
165
|
+
# Add a custom event set
|
166
|
+
event_set :visions
|
170
167
|
end
|
171
168
|
|
172
169
|
with Vision
|
@@ -196,7 +193,6 @@ end
|
|
196
193
|
# Create a user, fill their pockets, and delete them.
|
197
194
|
Fauna::Client.context($fauna) do
|
198
195
|
taran = Fauna::User.new(
|
199
|
-
name: "Taran",
|
200
196
|
email: "taran@example.com",
|
201
197
|
password: "secret")
|
202
198
|
|
@@ -212,7 +208,7 @@ end
|
|
212
208
|
```ruby
|
213
209
|
# Create, find, update, and destroy Pigs.
|
214
210
|
Fauna::Client.context($fauna) do
|
215
|
-
@pig = Pig.create!(name: "Henwen",
|
211
|
+
@pig = Pig.create!(name: "Henwen", unique_id: "henwen")
|
216
212
|
|
217
213
|
@pig = Pig.find(@pig.ref)
|
218
214
|
@pig.update(title: "Oracular Swine")
|
@@ -224,15 +220,15 @@ Fauna::Client.context($fauna) do
|
|
224
220
|
end
|
225
221
|
```
|
226
222
|
|
227
|
-
###
|
223
|
+
### Event Sets
|
228
224
|
|
229
|
-
[
|
230
|
-
bidirectional event collections.
|
225
|
+
[Event Sets](https://fauna.org/API#event-sets) are high-cardinality,
|
226
|
+
bidirectional event collections. Event sets must be declared in the
|
231
227
|
Schema.
|
232
228
|
|
233
229
|
```ruby
|
234
230
|
Fauna::Client.context($fauna) do
|
235
|
-
@pig = Pig.create!(name: "Henwen",
|
231
|
+
@pig = Pig.create!(name: "Henwen", unique_id: "henwen")
|
236
232
|
|
237
233
|
@vision = Vision.create!(pronouncement: "In an ominous tower...")
|
238
234
|
@pig.visions.add @vision
|
@@ -261,7 +257,7 @@ end
|
|
261
257
|
|
262
258
|
Please see the Fauna [REST Documentation](https://fauna.org/API) for a
|
263
259
|
complete API reference, or look in
|
264
|
-
[`/
|
260
|
+
[`/test`](https://github.com/fauna/fauna-ruby/tree/master/test) for
|
265
261
|
more examples.
|
266
262
|
|
267
263
|
## Contributing
|
data/fauna.gemspec
CHANGED
@@ -2,22 +2,22 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "fauna"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Fauna, Inc."]
|
9
|
-
s.date = "2013-02
|
9
|
+
s.date = "2013-03-02"
|
10
10
|
s.description = "Official Ruby client for the Fauna API."
|
11
11
|
s.email = ""
|
12
|
-
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/fauna.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/ddl.rb", "lib/fauna/model.rb", "lib/fauna/model/class.rb", "lib/fauna/model/
|
13
|
-
s.files = ["CHANGELOG", "Gemfile", "LICENSE", "Manifest", "README.md", "Rakefile", "fauna.gemspec", "lib/fauna.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/ddl.rb", "lib/fauna/model.rb", "lib/fauna/model/class.rb", "lib/fauna/model/
|
12
|
+
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/fauna.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/ddl.rb", "lib/fauna/model.rb", "lib/fauna/model/class.rb", "lib/fauna/model/event_set.rb", "lib/fauna/model/publisher.rb", "lib/fauna/model/user.rb", "lib/fauna/rails.rb", "lib/fauna/resource.rb"]
|
13
|
+
s.files = ["CHANGELOG", "Gemfile", "LICENSE", "Manifest", "README.md", "Rakefile", "fauna.gemspec", "lib/fauna.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/ddl.rb", "lib/fauna/model.rb", "lib/fauna/model/class.rb", "lib/fauna/model/event_set.rb", "lib/fauna/model/publisher.rb", "lib/fauna/model/user.rb", "lib/fauna/rails.rb", "lib/fauna/resource.rb", "test/client_test.rb", "test/connection_test.rb", "test/fixtures.rb", "test/model/association_test.rb", "test/model/class_test.rb", "test/model/event_set_test.rb", "test/model/publisher_test.rb", "test/model/user_test.rb", "test/model/validation_test.rb", "test/readme_test.rb", "test/test_helper.rb"]
|
14
14
|
s.homepage = "http://fauna.github.com/fauna/"
|
15
15
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Fauna", "--main", "README.md"]
|
16
16
|
s.require_paths = ["lib"]
|
17
17
|
s.rubyforge_project = "fauna"
|
18
18
|
s.rubygems_version = "1.8.23"
|
19
19
|
s.summary = "Official Ruby client for the Fauna API."
|
20
|
-
s.test_files = ["test/client_test.rb", "test/connection_test.rb", "test/model/association_test.rb", "test/model/class_test.rb", "test/model/
|
20
|
+
s.test_files = ["test/client_test.rb", "test/connection_test.rb", "test/model/association_test.rb", "test/model/class_test.rb", "test/model/event_set_test.rb", "test/model/publisher_test.rb", "test/model/user_test.rb", "test/model/validation_test.rb", "test/readme_test.rb", "test/test_helper.rb"]
|
21
21
|
|
22
22
|
if s.respond_to? :specification_version then
|
23
23
|
s.specification_version = 3
|
data/lib/fauna.rb
CHANGED
@@ -23,9 +23,8 @@ require "fauna/client"
|
|
23
23
|
require "fauna/resource"
|
24
24
|
require "fauna/model"
|
25
25
|
require "fauna/model/class"
|
26
|
-
require "fauna/model/follow"
|
27
26
|
require "fauna/model/publisher"
|
28
|
-
require "fauna/model/
|
27
|
+
require "fauna/model/event_set"
|
29
28
|
require "fauna/model/user"
|
30
29
|
require "fauna/ddl"
|
31
30
|
|
@@ -33,30 +32,29 @@ module Fauna
|
|
33
32
|
|
34
33
|
DEFAULT_BLOCK = proc do
|
35
34
|
with User, class_name: "users"
|
36
|
-
with User::
|
37
|
-
with
|
38
|
-
with
|
39
|
-
with
|
40
|
-
with ClassSettings, class_name: "classes"
|
35
|
+
with User::Config, class_name: "users/config"
|
36
|
+
with EventSetPage, class_name: "sets"
|
37
|
+
with EventSetConfig, class_name: "sets/config"
|
38
|
+
with ClassConfig, class_name: "classes/config"
|
41
39
|
with Publisher, class_name: "publisher"
|
42
40
|
end
|
43
41
|
|
44
42
|
def self.configure_schema!
|
45
|
-
@
|
43
|
+
@classes = {}
|
46
44
|
@schema = Fauna::DDL.new
|
47
|
-
@
|
45
|
+
@blocks.each { |blk| @schema.instance_eval(&blk) }
|
48
46
|
@schema.configure!
|
49
47
|
nil
|
50
48
|
end
|
51
49
|
|
52
50
|
def self.schema(&block)
|
53
|
-
@
|
51
|
+
@blocks << block
|
54
52
|
configure_schema!
|
55
53
|
end
|
56
54
|
|
57
55
|
|
58
56
|
def self.reset_schema!
|
59
|
-
@
|
57
|
+
@blocks = [DEFAULT_BLOCK]
|
60
58
|
configure_schema!
|
61
59
|
end
|
62
60
|
|
@@ -67,25 +65,25 @@ module Fauna
|
|
67
65
|
|
68
66
|
# these should be private to the gem
|
69
67
|
|
70
|
-
def self.exists_class_for_name?(
|
71
|
-
!!@
|
68
|
+
def self.exists_class_for_name?(fauna_class)
|
69
|
+
!!@classes[fauna_class]
|
72
70
|
end
|
73
71
|
|
74
|
-
def self.add_class(
|
75
|
-
klass.
|
76
|
-
@
|
77
|
-
@
|
72
|
+
def self.add_class(fauna_class, klass)
|
73
|
+
klass.fauna_class = fauna_class.to_s
|
74
|
+
@classes.delete_if { |_, v| v == klass }
|
75
|
+
@classes[fauna_class.to_s] = klass
|
78
76
|
end
|
79
77
|
|
80
|
-
def self.class_for_name(
|
81
|
-
@
|
82
|
-
if
|
78
|
+
def self.class_for_name(fauna_class)
|
79
|
+
@classes[fauna_class] ||=
|
80
|
+
if fauna_class =~ %r{^classes/[^/]+$}
|
83
81
|
klass = begin $1.classify.constantize rescue NameError; nil end
|
84
|
-
if klass.nil? || klass >= Fauna::Class || klass.
|
82
|
+
if klass.nil? || klass >= Fauna::Class || klass.fauna_class # e.g. already associated with another fauna_class
|
85
83
|
klass = ::Class.new(Fauna::Class)
|
86
84
|
end
|
87
85
|
|
88
|
-
klass.
|
86
|
+
klass.fauna_class = fauna_class
|
89
87
|
klass
|
90
88
|
else
|
91
89
|
::Class.new(Fauna::Resource)
|
data/lib/fauna/client.rb
CHANGED
data/lib/fauna/connection.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
module Fauna
|
2
2
|
class Connection
|
3
|
-
API_VERSION = 0
|
4
|
-
|
5
3
|
class Error < RuntimeError
|
6
4
|
attr_reader :param_errors
|
7
5
|
|
@@ -37,6 +35,7 @@ module Fauna
|
|
37
35
|
|
38
36
|
def initialize(params={})
|
39
37
|
@logger = params[:logger] || nil
|
38
|
+
@api_version = params[:version] || "v1/"
|
40
39
|
|
41
40
|
if ENV["FAUNA_DEBUG"]
|
42
41
|
@logger = Logger.new(STDERR)
|
@@ -54,24 +53,26 @@ module Fauna
|
|
54
53
|
elsif params[:email] and params[:password]
|
55
54
|
"#{CGI.escape(params[:email])}:#{CGI.escape(params[:password])}"
|
56
55
|
else
|
57
|
-
raise
|
56
|
+
raise TypeError
|
58
57
|
end
|
58
|
+
rescue TypeError
|
59
|
+
raise ArgumentError, "Credentials must be in the form of a hash containing either :publisher_key, :client_key, or :token, or both :email and :password."
|
59
60
|
end
|
60
61
|
|
61
62
|
def get(ref, query = nil)
|
62
|
-
|
63
|
+
parse(execute(:get, ref, nil, query))
|
63
64
|
end
|
64
65
|
|
65
66
|
def post(ref, data = nil)
|
66
|
-
|
67
|
+
parse(execute(:post, ref, data))
|
67
68
|
end
|
68
69
|
|
69
70
|
def put(ref, data = nil)
|
70
|
-
|
71
|
+
parse(execute(:put, ref, data))
|
71
72
|
end
|
72
73
|
|
73
74
|
def patch(ref, data = nil)
|
74
|
-
|
75
|
+
parse(execute(:patch, ref, data))
|
75
76
|
end
|
76
77
|
|
77
78
|
def delete(ref, data = nil)
|
@@ -81,6 +82,16 @@ module Fauna
|
|
81
82
|
|
82
83
|
private
|
83
84
|
|
85
|
+
def parse(response)
|
86
|
+
obj = if response.empty?
|
87
|
+
{}
|
88
|
+
else
|
89
|
+
JSON.parse(response)
|
90
|
+
end
|
91
|
+
obj.merge!("headers" => response.headers.stringify_keys)
|
92
|
+
obj
|
93
|
+
end
|
94
|
+
|
84
95
|
def log(indent)
|
85
96
|
Array(yield).map do |string|
|
86
97
|
string.split("\n")
|
@@ -123,7 +134,7 @@ module Fauna
|
|
123
134
|
end
|
124
135
|
|
125
136
|
def url(ref)
|
126
|
-
"https://#{@credentials}@rest.fauna.org
|
137
|
+
"https://#{@credentials}@rest.fauna.org/#{@api_version}#{ref}"
|
127
138
|
end
|
128
139
|
end
|
129
140
|
end
|
data/lib/fauna/ddl.rb
CHANGED
@@ -15,41 +15,42 @@ module Fauna
|
|
15
15
|
|
16
16
|
# resources
|
17
17
|
|
18
|
-
def with(
|
19
|
-
res = ResourceDDL.new(
|
18
|
+
def with(klass, args = {}, &block)
|
19
|
+
res = ResourceDDL.new(klass, args)
|
20
20
|
res.instance_eval(&block) if block_given?
|
21
21
|
@ddls << res
|
22
22
|
nil
|
23
23
|
end
|
24
24
|
|
25
25
|
class ResourceDDL
|
26
|
-
def initialize(
|
27
|
-
@
|
28
|
-
@class =
|
29
|
-
@
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
raise ArgmentError "#{@class} must be a subclass of #{max_super(@class_name)}."
|
26
|
+
def initialize(klass, args = {})
|
27
|
+
@event_sets = []
|
28
|
+
@class = klass
|
29
|
+
@fauna_class = args[:class_name] || derived_fauna_class(@class)
|
30
|
+
|
31
|
+
unless @class <= max_super(@fauna_class)
|
32
|
+
raise ArgumentError, "#{@class} must be a subclass of #{max_super(@fauna_class)}."
|
34
33
|
end
|
35
34
|
|
36
|
-
|
35
|
+
if @fauna_class =~ %r{^classes/[^/]+$} && @fauna_class != 'classes/config'
|
36
|
+
@meta = Fauna::ClassConfig.alloc('ref' => "#{@fauna_class}/config")
|
37
|
+
end
|
37
38
|
end
|
38
39
|
|
39
40
|
def configure!
|
40
|
-
Fauna.add_class(@
|
41
|
+
Fauna.add_class(@fauna_class, @class) if @class
|
41
42
|
end
|
42
43
|
|
43
44
|
def load!
|
44
45
|
@meta.save! if @meta
|
45
|
-
@
|
46
|
+
@event_sets.each { |t| t.load! }
|
46
47
|
end
|
47
48
|
|
48
|
-
def
|
49
|
+
def event_set(*name)
|
49
50
|
args = name.last.is_a?(Hash) ? name.pop : {}
|
50
|
-
@class.send :
|
51
|
+
@class.send :event_set, *name
|
51
52
|
|
52
|
-
name.each { |n| @
|
53
|
+
name.each { |n| @event_sets << EventSetDDL.new(@fauna_class, n, args) }
|
53
54
|
end
|
54
55
|
|
55
56
|
def field(*name)
|
@@ -66,34 +67,30 @@ module Fauna
|
|
66
67
|
case name
|
67
68
|
when "users" then Fauna::User
|
68
69
|
when "publisher" then Fauna::Publisher
|
70
|
+
when "classes/config" then Fauna::Resource
|
69
71
|
when %r{^classes/[^/]+$} then Fauna::Class
|
70
72
|
else Fauna::Resource
|
71
73
|
end
|
72
74
|
end
|
73
75
|
|
74
|
-
def
|
75
|
-
if
|
76
|
+
def derived_fauna_class(klass)
|
77
|
+
if klass < Fauna::User
|
76
78
|
"users"
|
77
|
-
elsif
|
79
|
+
elsif klass < Fauna::Publisher
|
78
80
|
"publisher"
|
79
|
-
elsif
|
80
|
-
"classes/#{
|
81
|
+
elsif klass < Fauna::Class
|
82
|
+
"classes/#{klass.name.tableize}"
|
81
83
|
else
|
82
|
-
raise ArgumentError, "Must specify a :class_name for non-default resource class #{
|
84
|
+
raise ArgumentError, "Must specify a :class_name for non-default resource class #{klass.name}"
|
83
85
|
end
|
84
86
|
end
|
85
87
|
end
|
86
88
|
|
87
|
-
#
|
88
|
-
|
89
|
-
def timeline(*name)
|
90
|
-
args = name.last.is_a?(Hash) ? name.pop : {}
|
91
|
-
name.each { |n| @ddls << TimelineDDL.new(nil, n, args) }
|
92
|
-
end
|
89
|
+
# event_sets
|
93
90
|
|
94
|
-
class
|
91
|
+
class EventSetDDL
|
95
92
|
def initialize(parent_class, name, args)
|
96
|
-
@meta =
|
93
|
+
@meta = EventSetConfig.new(parent_class, name, args)
|
97
94
|
end
|
98
95
|
|
99
96
|
def configure!
|
data/lib/fauna/model.rb
CHANGED
@@ -17,17 +17,20 @@ module Fauna
|
|
17
17
|
# TODO: use proper class here
|
18
18
|
def self.find_by_id(id)
|
19
19
|
ref =
|
20
|
-
if self <= Fauna::User
|
21
|
-
"users/#{id}"
|
22
|
-
elsif self <= Fauna::User::Settings
|
23
|
-
"users/#{id}/settings"
|
20
|
+
if self <= Fauna::User::Config
|
21
|
+
"users/#{id}/config"
|
24
22
|
else
|
25
|
-
"
|
23
|
+
"#{fauna_class}/#{id}"
|
26
24
|
end
|
27
25
|
|
28
26
|
Fauna::Resource.find(ref)
|
29
27
|
end
|
30
28
|
|
29
|
+
|
30
|
+
def self.find_by_unique_id(unique_id)
|
31
|
+
find("#{fauna_class}/unique_id/#{unique_id}")
|
32
|
+
end
|
33
|
+
|
31
34
|
def id
|
32
35
|
ref.split("/").last
|
33
36
|
end
|
data/lib/fauna/model/class.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Fauna
|
2
|
-
class
|
2
|
+
class ClassConfig < Fauna::Resource; end
|
3
3
|
|
4
4
|
class Class < Fauna::Model
|
5
5
|
class << self
|
@@ -8,42 +8,31 @@ module Fauna
|
|
8
8
|
Fauna.add_class(fc, base) unless Fauna.exists_class_for_name?(fc)
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
|
11
|
+
def config_ref
|
12
|
+
"#{fauna_class}/config"
|
13
13
|
end
|
14
14
|
|
15
15
|
def data
|
16
|
-
Fauna::Resource.find(
|
16
|
+
Fauna::Resource.find(config_ref).data
|
17
17
|
end
|
18
18
|
|
19
19
|
def update_data!(hash = {})
|
20
|
-
meta = Fauna::Resource.find(
|
20
|
+
meta = Fauna::Resource.find(config_ref)
|
21
21
|
block_given? ? yield(meta.data) : meta.data = hash
|
22
22
|
meta.save!
|
23
23
|
end
|
24
24
|
|
25
25
|
def update_data(hash = {})
|
26
|
-
meta = Fauna::Resource.find(
|
26
|
+
meta = Fauna::Resource.find(config_ref)
|
27
27
|
block_given? ? yield(meta.data) : meta.data = hash
|
28
28
|
meta.save
|
29
29
|
end
|
30
|
-
|
31
|
-
def __class_name__
|
32
|
-
@__class_name__ ||= begin
|
33
|
-
raise MissingMigration, "Class #{name} has not been added to Fauna.schema." if !fauna_class_name
|
34
|
-
fauna_class_name[8..-1]
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def find_by_external_id(external_id)
|
39
|
-
find_by("instances", :external_id => external_id, :class => __class_name__).first
|
40
|
-
end
|
41
30
|
end
|
42
31
|
|
43
32
|
private
|
44
33
|
|
45
34
|
def post
|
46
|
-
Fauna::Client.post(
|
35
|
+
Fauna::Client.post(self.class.fauna_class, struct)
|
47
36
|
end
|
48
37
|
end
|
49
38
|
end
|
@@ -1,30 +1,29 @@
|
|
1
1
|
|
2
2
|
module Fauna
|
3
|
-
class
|
3
|
+
class Event
|
4
4
|
|
5
|
-
attr_reader :ts, :
|
5
|
+
attr_reader :ts, :set_ref, :resource_ref, :action
|
6
6
|
|
7
7
|
def initialize(attrs)
|
8
8
|
# TODO v1
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@ts, @action, @resource_ref = *attrs
|
9
|
+
@ts = attrs['ts']
|
10
|
+
@set_ref = attrs['set']
|
11
|
+
@resource_ref = attrs['resource']
|
12
|
+
@action = attrs['action']
|
14
13
|
end
|
15
14
|
|
16
15
|
def resource
|
17
16
|
Fauna::Resource.find(resource_ref)
|
18
17
|
end
|
19
18
|
|
20
|
-
def
|
21
|
-
|
19
|
+
def set
|
20
|
+
EventSet.new(set_ref)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
|
-
class
|
24
|
+
class EventSetPage < Fauna::Resource
|
26
25
|
def events
|
27
|
-
@events ||= struct['events'].map { |e|
|
26
|
+
@events ||= struct['events'].map { |e| Event.new(e) }
|
28
27
|
end
|
29
28
|
|
30
29
|
def any?
|
@@ -32,7 +31,7 @@ module Fauna
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def resources
|
35
|
-
# TODO duplicates can exist in the local
|
34
|
+
# TODO duplicates can exist in the local event_set. remove w/ v1
|
36
35
|
seen = {}
|
37
36
|
events.inject([]) do |a, ev|
|
38
37
|
if (ev.action == 'create' && !seen[ev.resource_ref])
|
@@ -45,7 +44,7 @@ module Fauna
|
|
45
44
|
end
|
46
45
|
end
|
47
46
|
|
48
|
-
class
|
47
|
+
class EventSet
|
49
48
|
attr_reader :ref
|
50
49
|
|
51
50
|
def initialize(ref)
|
@@ -53,7 +52,7 @@ module Fauna
|
|
53
52
|
end
|
54
53
|
|
55
54
|
def page(query = nil)
|
56
|
-
|
55
|
+
EventSetPage.find(ref, query)
|
57
56
|
end
|
58
57
|
|
59
58
|
def events(query = nil)
|
@@ -83,10 +82,10 @@ module Fauna
|
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
86
|
-
class
|
87
|
-
def initialize(name, attrs = {})
|
85
|
+
class EventSetConfig < Fauna::Resource
|
86
|
+
def initialize(parent_class, name, attrs = {})
|
88
87
|
super(attrs)
|
89
|
-
struct['ref'] = "
|
88
|
+
struct['ref'] = "#{parent_class}/sets/#{name}/config"
|
90
89
|
end
|
91
90
|
end
|
92
91
|
end
|
data/lib/fauna/model/user.rb
CHANGED
@@ -2,37 +2,22 @@
|
|
2
2
|
module Fauna
|
3
3
|
class User < Fauna::Model
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
class Settings < Fauna::Model; end
|
5
|
+
class Config < Fauna::Model; end
|
8
6
|
|
9
7
|
def self.self
|
10
8
|
find("users/self")
|
11
9
|
end
|
12
10
|
|
13
11
|
def self.find_by_email(email)
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.find_by_external_id(external_id)
|
18
|
-
find_by("users", :external_id => external_id).first
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.find_by_name(name)
|
22
|
-
find_by("users", :name => name)
|
12
|
+
find("users/email/#{email}")
|
23
13
|
end
|
24
14
|
|
25
15
|
def email; struct['email']; end
|
26
16
|
|
27
17
|
def password; struct['password']; end
|
28
18
|
|
29
|
-
|
30
|
-
|
31
|
-
struct['name']
|
32
|
-
end
|
33
|
-
|
34
|
-
def settings
|
35
|
-
Fauna::User::Settings.find("#{ref}/settings")
|
19
|
+
def config
|
20
|
+
Fauna::User::Config.find("#{ref}/config")
|
36
21
|
end
|
37
22
|
|
38
23
|
private
|
data/lib/fauna/resource.rb
CHANGED
@@ -2,13 +2,17 @@ module Fauna
|
|
2
2
|
class Resource
|
3
3
|
|
4
4
|
def self.fields; @fields ||= [] end
|
5
|
-
def self.
|
5
|
+
def self.event_sets; @event_sets ||= [] end
|
6
6
|
def self.references; @references ||= [] end
|
7
7
|
|
8
8
|
# config DSL
|
9
9
|
|
10
10
|
class << self
|
11
|
-
attr_accessor :
|
11
|
+
attr_accessor :fauna_class
|
12
|
+
|
13
|
+
def fauna_class
|
14
|
+
@fauna_class or raise MissingMigration, "Class #{name} has not been added to Fauna.schema."
|
15
|
+
end
|
12
16
|
|
13
17
|
private
|
14
18
|
|
@@ -23,15 +27,15 @@ module Fauna
|
|
23
27
|
end
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
30
|
+
def event_set(*names)
|
27
31
|
args = names.last.is_a?(Hash) ? names.pop : {}
|
28
32
|
|
29
33
|
names.each do |name|
|
30
|
-
|
31
|
-
|
32
|
-
|
34
|
+
set_name = args[:internal] ? name.to_s : "sets/#{name}"
|
35
|
+
event_sets << set_name
|
36
|
+
event_sets.uniq!
|
33
37
|
|
34
|
-
define_method(name.to_s) { Fauna::
|
38
|
+
define_method(name.to_s) { Fauna::EventSet.new("#{ref}/#{set_name}") }
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
@@ -62,7 +66,7 @@ module Fauna
|
|
62
66
|
|
63
67
|
def self.find(ref, query = nil)
|
64
68
|
res = Fauna::Client.get(ref, query)
|
65
|
-
Fauna.class_for_name(res.
|
69
|
+
Fauna.class_for_name(res.fauna_class).alloc(res.to_hash)
|
66
70
|
end
|
67
71
|
|
68
72
|
def self.create(*args)
|
@@ -89,17 +93,13 @@ module Fauna
|
|
89
93
|
end
|
90
94
|
|
91
95
|
def ref; struct['ref'] end
|
96
|
+
def fauna_class; struct['class'] end
|
92
97
|
def ts; struct['ts'] end
|
93
98
|
def deleted; struct['deleted'] end
|
94
|
-
def
|
99
|
+
def unique_id; struct['unique_id'] end
|
95
100
|
def data; struct['data'] ||= {} end
|
96
101
|
def references; struct['references'] ||= {} end
|
97
|
-
def changes;
|
98
|
-
def user_follows; Timeline.new("#{ref}/follows/users") end
|
99
|
-
def user_followers; Timeline.new("#{ref}/followers/users") end
|
100
|
-
def instance_follows; Timeline.new("#{ref}/follows/instances") end
|
101
|
-
def instance_followers; Timeline.new("#{ref}/followers/instances") end
|
102
|
-
def local; Timeline.new("#{ref}/local") end
|
102
|
+
def changes; EventSet.new("#{ref}/changes") end
|
103
103
|
|
104
104
|
def eql?(other)
|
105
105
|
self.class.equal?(other.class) && self.ref == other.ref && self.ref != nil
|
@@ -170,42 +170,6 @@ module Fauna
|
|
170
170
|
|
171
171
|
alias :destroy :delete
|
172
172
|
|
173
|
-
# TODO eliminate/simplify once v1 drops
|
174
|
-
|
175
|
-
def fauna_class_name
|
176
|
-
@_fauna_class_name ||=
|
177
|
-
case ref
|
178
|
-
when %r{^users/[^/]+$}
|
179
|
-
"users"
|
180
|
-
when %r{^instances/[^/]+$}
|
181
|
-
"classes/#{struct['class']}"
|
182
|
-
when %r{^[^/]+/[^/]+/follows/[^/]+/[^/]+$}
|
183
|
-
"follows"
|
184
|
-
when %r{^.+/timelines/[^/]+$}
|
185
|
-
"timelines"
|
186
|
-
when %r{^.+/changes$}
|
187
|
-
"timelines"
|
188
|
-
when %r{^.+/local$}
|
189
|
-
"timelines"
|
190
|
-
when %r{^.+/follows/[^/]+$}
|
191
|
-
"timelines"
|
192
|
-
when %r{^.+/followers/[^/]+$}
|
193
|
-
"timelines"
|
194
|
-
when %r{^timelines/[^/]+$}
|
195
|
-
"timelines/settings"
|
196
|
-
when %r{^classes/[^/]+$}
|
197
|
-
"classes"
|
198
|
-
when %r{^users/[^/]+/settings$}
|
199
|
-
"users/settings"
|
200
|
-
when "publisher/settings"
|
201
|
-
"publisher/settings"
|
202
|
-
when "publisher"
|
203
|
-
"publisher"
|
204
|
-
else
|
205
|
-
nil
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
173
|
private
|
210
174
|
|
211
175
|
# TODO: make this configurable, and possible to invert to a white list
|
data/test/fixtures.rb
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
# end
|
8
8
|
|
9
9
|
class Fauna::User
|
10
|
+
field :name
|
10
11
|
field :pockets
|
11
12
|
end
|
12
13
|
|
@@ -43,7 +44,7 @@ end
|
|
43
44
|
|
44
45
|
Fauna.schema do |f|
|
45
46
|
with Pig, :class_name => "classes/pigs" do
|
46
|
-
|
47
|
+
event_set :visions
|
47
48
|
end
|
48
49
|
|
49
50
|
with Pigkeeper
|
@@ -51,7 +52,7 @@ Fauna.schema do |f|
|
|
51
52
|
with Vision
|
52
53
|
|
53
54
|
with MessageBoard, :class_name => "classes/board" do
|
54
|
-
|
55
|
+
event_set :posts
|
55
56
|
end
|
56
57
|
|
57
58
|
with Post
|
@@ -10,7 +10,7 @@ class AssociationTest < MiniTest::Unit::TestCase
|
|
10
10
|
@pig.visions.add @vision
|
11
11
|
end
|
12
12
|
|
13
|
-
def
|
13
|
+
def test_event_set
|
14
14
|
assert_equal @pig.visions.page.events.first.resource, @vision
|
15
15
|
assert @pig.visions.page.events.first.resource.pronouncement
|
16
16
|
end
|
data/test/model/class_test.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
# TODO use association_test classes
|
4
4
|
|
5
|
-
class
|
5
|
+
class EventSetTest < ActiveModel::TestCase
|
6
6
|
# include ActiveModel::Lint::Tests
|
7
7
|
|
8
8
|
def setup
|
@@ -12,7 +12,7 @@ class TimelineTest < ActiveModel::TestCase
|
|
12
12
|
|
13
13
|
def test_page
|
14
14
|
page = @model.posts.page
|
15
|
-
assert_equal page.ref, "#{@model.ref}/
|
15
|
+
assert_equal page.ref, "#{@model.ref}/sets/posts"
|
16
16
|
assert_equal page.events.size, 0
|
17
17
|
end
|
18
18
|
|
@@ -22,29 +22,17 @@ class TimelineTest < ActiveModel::TestCase
|
|
22
22
|
assert @model.posts.page.events.any?
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def test_event_set_add
|
26
26
|
@model.posts.add(Post.create(:body => "Goodbye"))
|
27
27
|
page = @model.posts.page
|
28
28
|
assert_equal page.events.size, 1
|
29
29
|
assert_equal page.events[0].resource.body, "Goodbye"
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def test_event_set_remove
|
33
33
|
@model.posts.add(Post.create(:body => "Hello"))
|
34
34
|
page = @model.posts.page
|
35
35
|
assert_equal page.events.size, 1
|
36
36
|
@model.posts.remove(page.events[0].resource)
|
37
37
|
end
|
38
|
-
|
39
|
-
def test_local
|
40
|
-
user = Fauna::User.create!(:name => "user", :email => email)
|
41
|
-
|
42
|
-
follow = Fauna::Follow.new(:follower => user, :resource => @model)
|
43
|
-
follow.save!
|
44
|
-
|
45
|
-
post = Post.create(:body => "Goodbye")
|
46
|
-
@model.posts.add(post)
|
47
|
-
|
48
|
-
assert(user.local.page.events.find { |e| e.resource_ref == post.ref })
|
49
|
-
end
|
50
38
|
end
|
data/test/model/user_test.rb
CHANGED
@@ -52,21 +52,16 @@ class UserTest < ActiveModel::TestCase
|
|
52
52
|
|
53
53
|
def test_find_by_email
|
54
54
|
user = Fauna::User.create(@attributes.merge(:email => "test@example.com"))
|
55
|
-
assert_equal
|
55
|
+
assert_equal user, Fauna::User.find_by_email("test@example.com")
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
user = Fauna::User.create(@attributes.merge(:name => "Gwystyl"))
|
60
|
-
assert_equal [user], Fauna::User.find_by_name("Gwystyl")
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_user_settings
|
58
|
+
def test_user_config
|
64
59
|
user = Fauna::User.create(@attributes)
|
65
|
-
assert_equal user.
|
60
|
+
assert_equal user.config.ref, "#{user.ref}/config"
|
66
61
|
end
|
67
62
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
63
|
+
def test_find_by_unique_id
|
64
|
+
user = Fauna::User.create(@attributes.merge(:unique_id => "henwen"))
|
65
|
+
assert_equal user, Fauna::User.find_by_unique_id("henwen")
|
66
|
+
end
|
72
67
|
end
|
@@ -7,17 +7,7 @@ class ClassValidationTest < MiniTest::Unit::TestCase
|
|
7
7
|
refute h.save
|
8
8
|
assert_equal ["can't be blank"], h.errors[:visited],
|
9
9
|
|
10
|
-
|
11
|
-
assert h.save
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_validates_presence_of
|
15
|
-
h = Fauna::User.new(:email => email, :password => password)
|
16
|
-
refute h.valid?
|
17
|
-
refute h.save
|
18
|
-
assert_equal ["can't be blank"], h.errors[:name]
|
19
|
-
|
20
|
-
h.name = "Llyan"
|
10
|
+
h.visited = true
|
21
11
|
assert h.save
|
22
12
|
end
|
23
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fauna
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02
|
12
|
+
date: 2013-03-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -137,9 +137,8 @@ extra_rdoc_files:
|
|
137
137
|
- lib/fauna/ddl.rb
|
138
138
|
- lib/fauna/model.rb
|
139
139
|
- lib/fauna/model/class.rb
|
140
|
-
- lib/fauna/model/
|
140
|
+
- lib/fauna/model/event_set.rb
|
141
141
|
- lib/fauna/model/publisher.rb
|
142
|
-
- lib/fauna/model/timeline.rb
|
143
142
|
- lib/fauna/model/user.rb
|
144
143
|
- lib/fauna/rails.rb
|
145
144
|
- lib/fauna/resource.rb
|
@@ -157,9 +156,8 @@ files:
|
|
157
156
|
- lib/fauna/ddl.rb
|
158
157
|
- lib/fauna/model.rb
|
159
158
|
- lib/fauna/model/class.rb
|
160
|
-
- lib/fauna/model/
|
159
|
+
- lib/fauna/model/event_set.rb
|
161
160
|
- lib/fauna/model/publisher.rb
|
162
|
-
- lib/fauna/model/timeline.rb
|
163
161
|
- lib/fauna/model/user.rb
|
164
162
|
- lib/fauna/rails.rb
|
165
163
|
- lib/fauna/resource.rb
|
@@ -168,9 +166,8 @@ files:
|
|
168
166
|
- test/fixtures.rb
|
169
167
|
- test/model/association_test.rb
|
170
168
|
- test/model/class_test.rb
|
171
|
-
- test/model/
|
169
|
+
- test/model/event_set_test.rb
|
172
170
|
- test/model/publisher_test.rb
|
173
|
-
- test/model/timeline_test.rb
|
174
171
|
- test/model/user_test.rb
|
175
172
|
- test/model/validation_test.rb
|
176
173
|
- test/readme_test.rb
|
@@ -210,9 +207,8 @@ test_files:
|
|
210
207
|
- test/connection_test.rb
|
211
208
|
- test/model/association_test.rb
|
212
209
|
- test/model/class_test.rb
|
213
|
-
- test/model/
|
210
|
+
- test/model/event_set_test.rb
|
214
211
|
- test/model/publisher_test.rb
|
215
|
-
- test/model/timeline_test.rb
|
216
212
|
- test/model/user_test.rb
|
217
213
|
- test/model/validation_test.rb
|
218
214
|
- test/readme_test.rb
|
data/lib/fauna/model/follow.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
|
2
|
-
module Fauna
|
3
|
-
class Follow < Fauna::Model
|
4
|
-
def self.find_by_follower_and_resource(follower, resource)
|
5
|
-
find(new(:follower => follower, :resource => resource).ref)
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize(attrs = {})
|
9
|
-
super({})
|
10
|
-
attrs.stringify_keys!
|
11
|
-
follower_ref = attrs['follower_ref']
|
12
|
-
follower_ref = attrs['follower'].ref if attrs['follower']
|
13
|
-
resource_ref = attrs['resource_ref']
|
14
|
-
resource_ref = attrs['resource'].ref if attrs['resource']
|
15
|
-
ref = "#{follower_ref}/follows/#{resource_ref}"
|
16
|
-
|
17
|
-
raise ArgumentError, "Follower ref is nil." if follower_ref.nil?
|
18
|
-
raise ArgumentError, "Resource ref is nil." if resource_ref.nil?
|
19
|
-
|
20
|
-
@struct = { 'ref' => ref, 'follower' => follower_ref, 'resource' => resource_ref }
|
21
|
-
end
|
22
|
-
|
23
|
-
def follower_ref
|
24
|
-
struct['follower']
|
25
|
-
end
|
26
|
-
|
27
|
-
def follower
|
28
|
-
Fauna::Resource.find(follower_ref)
|
29
|
-
end
|
30
|
-
|
31
|
-
def resource_ref
|
32
|
-
struct['resource']
|
33
|
-
end
|
34
|
-
|
35
|
-
def resource
|
36
|
-
Fauna::Resource.find(resource_ref)
|
37
|
-
end
|
38
|
-
|
39
|
-
def update(*args)
|
40
|
-
raise Fauna::Invalid, "Follows have nothing to update."
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/test/model/follow_test.rb
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
require File.expand_path('../../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class FollowTest < ActiveModel::TestCase
|
4
|
-
#include ActiveModel::Lint::Tests
|
5
|
-
|
6
|
-
def setup
|
7
|
-
super
|
8
|
-
@pig = Pig.create!
|
9
|
-
@pigkeeper = Pigkeeper.create! :visited => true, :pockets => 1
|
10
|
-
@attributes = {:follower => @pig, :resource => @pigkeeper}
|
11
|
-
@model = Fauna::Follow.new(@attributes)
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_create
|
15
|
-
follow = Fauna::Follow.create(@attributes)
|
16
|
-
assert follow.persisted?
|
17
|
-
assert follow.ref
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_save
|
21
|
-
follow = Fauna::Follow.new(@attributes)
|
22
|
-
follow.save
|
23
|
-
assert follow.persisted?
|
24
|
-
assert follow.ref
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_update
|
28
|
-
follow = Fauna::Follow.create(@attributes)
|
29
|
-
assert_raises(Fauna::Invalid) do
|
30
|
-
follow.update(@attributes)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_find
|
35
|
-
Fauna::Follow.create(@attributes)
|
36
|
-
follow = Fauna::Follow.find_by_follower_and_resource(@pig, @pigkeeper)
|
37
|
-
assert follow.persisted?
|
38
|
-
assert follow.ref
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_destroy
|
42
|
-
follow = Fauna::Follow.create(@attributes)
|
43
|
-
follow.destroy
|
44
|
-
assert !follow.persisted?
|
45
|
-
assert follow.ref
|
46
|
-
end
|
47
|
-
end
|