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 CHANGED
@@ -1,3 +1,5 @@
1
+ v0.2.2 Support for Fauna API version 1
2
+
1
3
  v0.1.2 Fauna::User.find_by_external_id returns a User or nil, not an Array.
2
4
 
3
5
  v0.1.1 Fix ActionDispatch::Reloader bug.
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/follow.rb
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/follow_test.rb
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(publisher_key: publisher_key, logger:
58
- Logger.new(STDERR))
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!(name: "Taran", email: "taran@example.com")
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(external_id: "taran77", name: "Taran")
94
+ user = Fauna::User.create(unique_id: "taran77")
93
95
 
94
96
  # fields
95
- user.ref # => "users/123"
96
- user.ts # => 1359579766996758
97
- user.deleted # => false
98
- user.external_id # => "taran77"
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
- # standard timelines
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 timelines themselves must be configured with an additional
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 timeline
169
- timeline :visions
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", external_id: "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
- ### Timelines
223
+ ### Event Sets
228
224
 
229
- [Timelines](https://fauna.org/API#timelines) are high-cardinality,
230
- bidirectional event collections. Timelines must be declared in the
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", external_id: "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
- [`/tests`](https://github.com/fauna/fauna-ruby/tree/master/test) for
260
+ [`/test`](https://github.com/fauna/fauna-ruby/tree/master/test) for
265
261
  more examples.
266
262
 
267
263
  ## Contributing
@@ -2,22 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "fauna"
5
- s.version = "0.1.2"
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-09"
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/follow.rb", "lib/fauna/model/publisher.rb", "lib/fauna/model/timeline.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/follow.rb", "lib/fauna/model/publisher.rb", "lib/fauna/model/timeline.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/follow_test.rb", "test/model/publisher_test.rb", "test/model/timeline_test.rb", "test/model/user_test.rb", "test/model/validation_test.rb", "test/readme_test.rb", "test/test_helper.rb"]
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/follow_test.rb", "test/model/publisher_test.rb", "test/model/timeline_test.rb", "test/model/user_test.rb", "test/model/validation_test.rb", "test/readme_test.rb", "test/test_helper.rb"]
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
@@ -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/timeline"
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::Settings, class_name: "users/settings"
37
- with Follow, class_name: "follows"
38
- with TimelinePage, class_name: "timelines"
39
- with TimelineSettings, class_name: "timelines/settings"
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
- @_classes = {}
43
+ @classes = {}
46
44
  @schema = Fauna::DDL.new
47
- @_blocks.each { |blk| @schema.instance_eval(&blk) }
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
- @_blocks << block
51
+ @blocks << block
54
52
  configure_schema!
55
53
  end
56
54
 
57
55
 
58
56
  def self.reset_schema!
59
- @_blocks = [DEFAULT_BLOCK]
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?(class_name)
71
- !!@_classes[class_name]
68
+ def self.exists_class_for_name?(fauna_class)
69
+ !!@classes[fauna_class]
72
70
  end
73
71
 
74
- def self.add_class(class_name, klass)
75
- klass.fauna_class_name = class_name.to_s
76
- @_classes.delete_if { |_, v| v == klass }
77
- @_classes[class_name.to_s] = klass
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(class_name)
81
- @_classes[class_name] ||=
82
- if class_name =~ %r{^classes/[^/]+$}
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.fauna_class_name
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.fauna_class_name = class_name
86
+ klass.fauna_class = fauna_class
89
87
  klass
90
88
  else
91
89
  ::Class.new(Fauna::Resource)
@@ -50,7 +50,7 @@ module Fauna
50
50
  def cohere(ref, res)
51
51
  @cache[ref] = res['resource'] if ref =~ %r{^users/self}
52
52
  @cache[res['resource']['ref']] = res['resource']
53
- @cache.merge!(res['references'])
53
+ @cache.merge!(res['references'] || {})
54
54
  end
55
55
  end
56
56
 
@@ -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 ArgumentError, "Credentials not defined."
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
- JSON.parse(execute(:get, ref, nil, query))
63
+ parse(execute(:get, ref, nil, query))
63
64
  end
64
65
 
65
66
  def post(ref, data = nil)
66
- JSON.parse(execute(:post, ref, data))
67
+ parse(execute(:post, ref, data))
67
68
  end
68
69
 
69
70
  def put(ref, data = nil)
70
- JSON.parse(execute(:put, ref, data))
71
+ parse(execute(:put, ref, data))
71
72
  end
72
73
 
73
74
  def patch(ref, data = nil)
74
- JSON.parse(execute(:patch, ref, data))
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/v#{API_VERSION}/#{ref}"
137
+ "https://#{@credentials}@rest.fauna.org/#{@api_version}#{ref}"
127
138
  end
128
139
  end
129
140
  end
@@ -15,41 +15,42 @@ module Fauna
15
15
 
16
16
  # resources
17
17
 
18
- def with(__class__, args = {}, &block)
19
- res = ResourceDDL.new(__class__, args)
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(__class__, args = {})
27
- @timelines = []
28
- @class = __class__
29
- @class_name = args[:class_name] || fauna_class_name(@class)
30
- @class.fauna_class_name = @class_name
31
-
32
- unless @class <= max_super(@class_name)
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
- @meta = Fauna::ClassSettings.alloc('ref' => @class_name) if @class_name =~ %r{^classes/[^/]+$}
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(@class_name, @class) if @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
- @timelines.each { |t| t.load! }
46
+ @event_sets.each { |t| t.load! }
46
47
  end
47
48
 
48
- def timeline(*name)
49
+ def event_set(*name)
49
50
  args = name.last.is_a?(Hash) ? name.pop : {}
50
- @class.send :timeline, *name
51
+ @class.send :event_set, *name
51
52
 
52
- name.each { |n| @timelines << TimelineDDL.new(@class_name, n, args) }
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 fauna_class_name(__class__)
75
- if __class__ < Fauna::User
76
+ def derived_fauna_class(klass)
77
+ if klass < Fauna::User
76
78
  "users"
77
- elsif __class__ < Fauna::Publisher
79
+ elsif klass < Fauna::Publisher
78
80
  "publisher"
79
- elsif __class__ < Fauna::Class
80
- "classes/#{__class__.name.tableize}"
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 #{__class__.name}"
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
- # timelines
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 TimelineDDL
91
+ class EventSetDDL
95
92
  def initialize(parent_class, name, args)
96
- @meta = TimelineSettings.new(name, args)
93
+ @meta = EventSetConfig.new(parent_class, name, args)
97
94
  end
98
95
 
99
96
  def configure!
@@ -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
- "instances/#{id}"
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
@@ -1,5 +1,5 @@
1
1
  module Fauna
2
- class ClassSettings < Fauna::Resource; end
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 ref
12
- fauna_class_name
11
+ def config_ref
12
+ "#{fauna_class}/config"
13
13
  end
14
14
 
15
15
  def data
16
- Fauna::Resource.find(fauna_class_name).data
16
+ Fauna::Resource.find(config_ref).data
17
17
  end
18
18
 
19
19
  def update_data!(hash = {})
20
- meta = Fauna::Resource.find(fauna_class_name)
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(fauna_class_name)
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("instances", struct.merge("class" => self.class.__class_name__))
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 TimelineEvent
3
+ class Event
4
4
 
5
- attr_reader :ts, :timeline_ref, :resource_ref, :action
5
+ attr_reader :ts, :set_ref, :resource_ref, :action
6
6
 
7
7
  def initialize(attrs)
8
8
  # TODO v1
9
- # @ts = attrs['ts']
10
- # @timeline_ref = attrs['timeline']
11
- # @resource_ref = attrs['resource']
12
- # @action = attrs['action']
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 timeline
21
- Timeline.new(timeline_ref)
19
+ def set
20
+ EventSet.new(set_ref)
22
21
  end
23
22
  end
24
23
 
25
- class TimelinePage < Fauna::Resource
24
+ class EventSetPage < Fauna::Resource
26
25
  def events
27
- @events ||= struct['events'].map { |e| TimelineEvent.new(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 timeline. remove w/ v1
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 Timeline
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
- TimelinePage.find(ref, query)
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 TimelineSettings < Fauna::Resource
87
- def initialize(name, attrs = {})
85
+ class EventSetConfig < Fauna::Resource
86
+ def initialize(parent_class, name, attrs = {})
88
87
  super(attrs)
89
- struct['ref'] = "timelines/#{name}"
88
+ struct['ref'] = "#{parent_class}/sets/#{name}/config"
90
89
  end
91
90
  end
92
91
  end
@@ -2,37 +2,22 @@
2
2
  module Fauna
3
3
  class User < Fauna::Model
4
4
 
5
- validates :name, :presence => true
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
- find_by("users", :email => email)
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
- # FIXME https://github.com/fauna/issues/issues/16
30
- def name
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
@@ -2,13 +2,17 @@ module Fauna
2
2
  class Resource
3
3
 
4
4
  def self.fields; @fields ||= [] end
5
- def self.timelines; @timelines ||= [] end
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 :fauna_class_name
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 timeline(*names)
30
+ def event_set(*names)
27
31
  args = names.last.is_a?(Hash) ? names.pop : {}
28
32
 
29
33
  names.each do |name|
30
- timeline_name = args[:internal] ? name.to_s : "timelines/#{name}"
31
- timelines << timeline_name
32
- timelines.uniq!
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::Timeline.new("#{ref}/#{timeline_name}") }
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.fauna_class_name).alloc(res.to_hash)
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 external_id; struct['external_id'] end
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; Timeline.new("#{ref}/changes") end
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
@@ -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
- timeline :visions
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
- timeline :posts
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 test_timeline
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
@@ -9,7 +9,8 @@ class ClassTest < ActiveModel::TestCase
9
9
  end
10
10
 
11
11
  def test_class_name
12
- assert_equal 'classes/pigs', Pig.ref
12
+ assert_equal 'classes/pigs', Pig.fauna_class
13
+ assert_equal 'classes/pigs/config', Pig.config_ref
13
14
  end
14
15
 
15
16
  def test_class_save
@@ -2,7 +2,7 @@ require File.expand_path('../../test_helper', __FILE__)
2
2
 
3
3
  # TODO use association_test classes
4
4
 
5
- class TimelineTest < ActiveModel::TestCase
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}/timelines/posts"
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 test_timeline_add
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 test_timeline_remove
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
@@ -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 [user], Fauna::User.find_by_email("test@example.com")
55
+ assert_equal user, Fauna::User.find_by_email("test@example.com")
56
56
  end
57
57
 
58
- def test_find_by_name
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.settings.ref, "#{user.ref}/settings"
60
+ assert_equal user.config.ref, "#{user.ref}/config"
66
61
  end
67
62
 
68
- # def test_find_by_external_id
69
- # user = Fauna::User.create(@attributes.merge(:external_id => "henwen"))
70
- # assert_equal [user], Fauna::User.find_by_external_id("henwen")
71
- # end
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
- h.visited = true
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.1.2
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-09 00:00:00.000000000 Z
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/follow.rb
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/follow.rb
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/follow_test.rb
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/follow_test.rb
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
@@ -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
@@ -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