fauna 1.3.4 → 2.0.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.
- checksums.yaml +5 -13
- data/CHANGELOG +2 -0
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.md +65 -102
- data/Rakefile +12 -20
- data/fauna.gemspec +19 -44
- data/lib/fauna.rb +12 -14
- data/lib/fauna/client.rb +225 -27
- data/lib/fauna/client_logger.rb +52 -0
- data/lib/fauna/context.rb +135 -0
- data/lib/fauna/errors.rb +181 -0
- data/lib/fauna/json.rb +60 -0
- data/lib/fauna/objects.rb +96 -0
- data/lib/fauna/query.rb +601 -0
- data/lib/fauna/request_result.rb +58 -0
- data/lib/fauna/util.rb +41 -0
- data/lib/fauna/version.rb +4 -0
- data/spec/client_logger_spec.rb +73 -0
- data/spec/client_spec.rb +202 -0
- data/spec/context_spec.rb +121 -0
- data/spec/errors_spec.rb +144 -0
- data/spec/fauna_helper.rb +87 -0
- data/spec/json_spec.rb +123 -0
- data/spec/query_spec.rb +675 -0
- data/spec/ref_spec.rb +77 -0
- data/spec/setref_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/util_spec.rb +19 -0
- metadata +65 -83
- data/Manifest +0 -25
- data/lib/fauna/cache.rb +0 -64
- data/lib/fauna/connection.rb +0 -152
- data/lib/fauna/named_resource.rb +0 -17
- data/lib/fauna/rails.rb +0 -120
- data/lib/fauna/resource.rb +0 -175
- data/lib/fauna/set.rb +0 -240
- data/lib/tasks/fauna.rake +0 -71
- data/test/class_test.rb +0 -65
- data/test/client_test.rb +0 -63
- data/test/connection_test.rb +0 -66
- data/test/database_test.rb +0 -48
- data/test/query_test.rb +0 -48
- data/test/readme_test.rb +0 -30
- data/test/set_test.rb +0 -71
- data/test/test_helper.rb +0 -86
data/lib/fauna/set.rb
DELETED
@@ -1,240 +0,0 @@
|
|
1
|
-
module Fauna
|
2
|
-
class Set
|
3
|
-
attr_reader :ref
|
4
|
-
|
5
|
-
def initialize(ref)
|
6
|
-
@ref = ref
|
7
|
-
end
|
8
|
-
|
9
|
-
def page(pagination = {})
|
10
|
-
SetPage.find(ref, {}, pagination)
|
11
|
-
end
|
12
|
-
|
13
|
-
def events(pagination = {})
|
14
|
-
EventsPage.find("#{ref}/events", {}, pagination)
|
15
|
-
end
|
16
|
-
|
17
|
-
# query DSL
|
18
|
-
|
19
|
-
def self.query(&block)
|
20
|
-
module_eval(&block)
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.union(*args)
|
24
|
-
QuerySet.new('union', *args)
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.intersection(*args)
|
28
|
-
QuerySet.new('intersection', *args)
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.difference(*args)
|
32
|
-
QuerySet.new('difference', *args)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.merge(*args)
|
36
|
-
QuerySet.new('merge', *args)
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.join(*args)
|
40
|
-
QuerySet.new('join', *args)
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.match(*args)
|
44
|
-
QuerySet.new('match', *args)
|
45
|
-
end
|
46
|
-
|
47
|
-
# although each is handled via the query DSL, it might make more
|
48
|
-
# sense to add it as a modifier on Set instances, similar to events.
|
49
|
-
|
50
|
-
def self.each(*args)
|
51
|
-
EachSet.new(*args)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
class QuerySet < Set
|
56
|
-
def initialize(function, *params)
|
57
|
-
@function = function
|
58
|
-
@params = params
|
59
|
-
end
|
60
|
-
|
61
|
-
def param_strings
|
62
|
-
if @function == 'match'
|
63
|
-
# Escape strings for match values
|
64
|
-
@params = @params[0..1] + @params[2..-1].collect do |p|
|
65
|
-
p.is_a?(String) ? p.inspect : p
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
@param_strings ||= @params.collect do |p|
|
70
|
-
if p.respond_to? :expr
|
71
|
-
p.expr
|
72
|
-
elsif p.respond_to? :ref
|
73
|
-
p.ref
|
74
|
-
else
|
75
|
-
p.to_s
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def expr
|
81
|
-
@expr ||= "#{@function}(#{param_strings.join(',')})"
|
82
|
-
end
|
83
|
-
|
84
|
-
def ref
|
85
|
-
"queries?q=#{expr}"
|
86
|
-
end
|
87
|
-
|
88
|
-
def page(pagination = {})
|
89
|
-
SetPage.find('queries', { 'q' => expr }, pagination)
|
90
|
-
end
|
91
|
-
|
92
|
-
def events(pagination = {})
|
93
|
-
EventsPage.find('queries', { 'q' => "events(#{expr})" }, pagination)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
class EachSet < QuerySet
|
98
|
-
def initialize(*params)
|
99
|
-
super('each', *params)
|
100
|
-
end
|
101
|
-
|
102
|
-
def events(pagination = {})
|
103
|
-
query = param_strings.first
|
104
|
-
subqueries = param_strings.drop(1).join ','
|
105
|
-
EventsPage.find('queries', { 'q' => "each(events(#{query}),#{subqueries})" }, pagination)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
class CustomSet < Set
|
110
|
-
def add(resource, time = nil)
|
111
|
-
self.class.add(self, resource, time)
|
112
|
-
end
|
113
|
-
|
114
|
-
def remove(resource, time = nil)
|
115
|
-
self.class.remove(self, resource, time)
|
116
|
-
end
|
117
|
-
|
118
|
-
def self.add(set, resource, time = nil)
|
119
|
-
set = set.ref if set.respond_to? :ref
|
120
|
-
resource = resource.ref if resource.respond_to? :ref
|
121
|
-
if time
|
122
|
-
Fauna::Client.put("#{set}/#{resource}/events/#{Fauna.usecs_from_time(time)}/create")
|
123
|
-
else
|
124
|
-
Fauna::Client.put("#{set}/#{resource}")
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def self.remove(set, resource, time = nil)
|
129
|
-
set = set.ref if set.respond_to? :ref
|
130
|
-
resource = resource.ref if resource.respond_to? :ref
|
131
|
-
if time
|
132
|
-
Fauna::Client.put("#{set}/#{resource}/events/#{Fauna.usecs_from_time(time)}/delete")
|
133
|
-
else
|
134
|
-
Fauna::Client.delete("#{set}/#{resource}")
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
class SetPage < Fauna::Resource
|
140
|
-
include Enumerable
|
141
|
-
|
142
|
-
def refs
|
143
|
-
@refs ||= struct['resources']
|
144
|
-
end
|
145
|
-
|
146
|
-
def each(&block)
|
147
|
-
refs.each(&block)
|
148
|
-
end
|
149
|
-
|
150
|
-
def empty?
|
151
|
-
refs.empty?
|
152
|
-
end
|
153
|
-
|
154
|
-
def fauna_count
|
155
|
-
struct['count']
|
156
|
-
end
|
157
|
-
|
158
|
-
def length
|
159
|
-
refs.length
|
160
|
-
end
|
161
|
-
|
162
|
-
def size
|
163
|
-
refs.size
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
class EventsPage < Fauna::Resource
|
168
|
-
include Enumerable
|
169
|
-
|
170
|
-
def events
|
171
|
-
@events ||= struct['events'].collect { |e| Event.new(e) }
|
172
|
-
end
|
173
|
-
|
174
|
-
def each(&block)
|
175
|
-
events.each(&block)
|
176
|
-
end
|
177
|
-
|
178
|
-
def empty?
|
179
|
-
events.empty?
|
180
|
-
end
|
181
|
-
|
182
|
-
def fauna_count
|
183
|
-
struct['count']
|
184
|
-
end
|
185
|
-
|
186
|
-
def length
|
187
|
-
events.length
|
188
|
-
end
|
189
|
-
|
190
|
-
def size
|
191
|
-
events.size
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
class Event
|
196
|
-
def initialize(attrs)
|
197
|
-
@attrs = attrs
|
198
|
-
end
|
199
|
-
|
200
|
-
def ref
|
201
|
-
"#{resource}/events/#{@attrs['ts']}/#{action}"
|
202
|
-
end
|
203
|
-
|
204
|
-
def event_ref
|
205
|
-
if set == resource
|
206
|
-
"#{resource}/events/#{@attrs['ts']}/#{action}"
|
207
|
-
else
|
208
|
-
"#{set}/#{resource}/events/#{@attrs['ts']}/#{action}"
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
def ts
|
213
|
-
Fauna.time_from_usecs(@attrs['ts'])
|
214
|
-
end
|
215
|
-
|
216
|
-
def resource
|
217
|
-
@attrs['resource']
|
218
|
-
end
|
219
|
-
|
220
|
-
def set
|
221
|
-
@attrs['set']
|
222
|
-
end
|
223
|
-
|
224
|
-
def action
|
225
|
-
@attrs['action']
|
226
|
-
end
|
227
|
-
|
228
|
-
def save
|
229
|
-
Fauna::Client.put(event_ref) if editable?
|
230
|
-
end
|
231
|
-
|
232
|
-
def delete
|
233
|
-
Fauna::Client.delete(event_ref) if editable?
|
234
|
-
end
|
235
|
-
|
236
|
-
def editable?
|
237
|
-
%w(create delete).include? action
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
data/lib/tasks/fauna.rake
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
|
2
|
-
task :environment
|
3
|
-
|
4
|
-
namespace :fauna do
|
5
|
-
desc 'Migrate your Fauna database to the latest version of your schema'
|
6
|
-
task :migrate => :environment do
|
7
|
-
puts "Migrating #{Rails.env} Fauna database schema"
|
8
|
-
Fauna::Client.context(Fauna.connection) do
|
9
|
-
Fauna.migrate_schema!
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
desc 'Completely reset your Fauna database'
|
14
|
-
task :reset => :environment do
|
15
|
-
if Rails.env.production?
|
16
|
-
puts "Won't reset #{Rails.env} Fauna database"
|
17
|
-
else
|
18
|
-
Fauna::Client.context(Fauna.root_connection) do
|
19
|
-
puts "Resetting #{Rails.env} Fauna database"
|
20
|
-
Fauna::Client.delete('everything')
|
21
|
-
end
|
22
|
-
Fauna.auth!
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
desc "Dump the contents of your Fauna database to 'test/fixtures/fauna'"
|
27
|
-
task :dump => :environment do
|
28
|
-
puts "Dumping #{Rails.env} Fauna database contents to #{Fauna::FIXTURES_DIR}"
|
29
|
-
Fauna::Client.context(Fauna.connection) do
|
30
|
-
FileUtils.mkdir_p(Fauna::FIXTURES_DIR)
|
31
|
-
|
32
|
-
class_configs = Fauna.connection.get('/classes')['references'] || {}
|
33
|
-
class_configs['users'] = nil
|
34
|
-
|
35
|
-
Dir.chdir(Fauna::FIXTURES_DIR) do
|
36
|
-
class_configs.each do |ref, value|
|
37
|
-
class_name = ref[0..-8]
|
38
|
-
FileUtils.mkdir_p(class_name)
|
39
|
-
|
40
|
-
Dir.chdir(class_name) do
|
41
|
-
# FIXME: shouldn't round trip JSON
|
42
|
-
File.open('config.json', 'w') { |f| f.write(value.to_json) } if value
|
43
|
-
(Fauna.connection.get(class_name)['references'] || {}).each do |inner_ref, inner_value|
|
44
|
-
File.open("#{inner_ref.split('/').last}.json", 'w') { |f| f.write(inner_value.to_json) }
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
desc 'Load the contents of your Fauna database'
|
53
|
-
task :load => :environment do
|
54
|
-
puts "Loading #{Rails.env} Fauna database contents from #{Fauna::FIXTURES_DIR}"
|
55
|
-
Fauna::Client.context(Fauna.connection) do
|
56
|
-
Dir.chdir(Fauna::FIXTURES_DIR) do
|
57
|
-
Dir['**/*.json'].collect do |filename|
|
58
|
-
value = JSON.parse(File.open(filename) { |f| f.read })
|
59
|
-
begin
|
60
|
-
Fauna.connection.put(value['ref'], value)
|
61
|
-
rescue Fauna::Connection::NotFound
|
62
|
-
Fauna.connection.post(value['ref'].split('/')[0..-2].join('/'), value)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
task :test => ['fauna:reset', 'fauna:migrate', 'fauna:load']
|
data/test/class_test.rb
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class ClassTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
super
|
6
|
-
@model = Fauna::Resource.new('classes/pigs')
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_new
|
10
|
-
settings = Fauna::Resource.new('settings', :ref => 'settings/12345678', :email => 'test@test.com')
|
11
|
-
user = Fauna::Resource.new('users', :ref => 'users/87654321')
|
12
|
-
assert user.data.object_id != settings.data.object_id
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_create
|
16
|
-
pig = Fauna::Resource.create 'classes/pigs', :data => { :visited => true }
|
17
|
-
assert_equal true, pig.data['visited']
|
18
|
-
assert pig.persisted?
|
19
|
-
assert pig.ref
|
20
|
-
refute pig.deleted?
|
21
|
-
refute_nil pig.deleted?
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_all
|
25
|
-
pig = Fauna::Resource.create 'classes/pigs'
|
26
|
-
assert Fauna::Set.new('classes/pigs/instances').page.include?(pig.ref)
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_save
|
30
|
-
pig = Fauna::Resource.new 'classes/pigs'
|
31
|
-
pig.save
|
32
|
-
assert pig.persisted?
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_update
|
36
|
-
pig = Fauna::Resource.new 'classes/pigs', :data => { :visited => false }
|
37
|
-
pig.save
|
38
|
-
pig.data['visited'] = true
|
39
|
-
pig.save
|
40
|
-
|
41
|
-
assert pig.data['visited']
|
42
|
-
assert_equal pig.events.length, 2
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_find
|
46
|
-
pig = Fauna::Resource.create 'classes/pigs'
|
47
|
-
pig1 = Fauna::Resource.find(pig.ref)
|
48
|
-
assert_equal pig.ref, pig1.ref
|
49
|
-
assert pig1.persisted?
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_delete
|
53
|
-
pig = Fauna::Resource.create 'classes/pigs'
|
54
|
-
pig.delete
|
55
|
-
assert pig.deleted?
|
56
|
-
end
|
57
|
-
|
58
|
-
def test_ts
|
59
|
-
pig = Fauna::Resource.create 'classes/pigs'
|
60
|
-
assert_instance_of(Time, pig.ts)
|
61
|
-
|
62
|
-
pig = Fauna::Resource.new 'classes/pigs'
|
63
|
-
assert_nil pig.ts
|
64
|
-
end
|
65
|
-
end
|
data/test/client_test.rb
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class ClientTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
super
|
6
|
-
@attributes = { 'name' => 'Princess Eilonwy', 'email' => email, 'password' => password }
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_database_context
|
10
|
-
Fauna::Client.context(@server_connection) do
|
11
|
-
user = Fauna::Client.post('users', @attributes)
|
12
|
-
user = Fauna::Client.get(user['ref'])
|
13
|
-
Fauna::Client.delete(user['ref'])
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_client_context
|
18
|
-
Fauna::Client.context(@client_connection) do
|
19
|
-
Fauna::Resource.create('users', @attributes)
|
20
|
-
|
21
|
-
Fauna::Client.context(@client_connection) do
|
22
|
-
assert_raises(Fauna::Connection::PermissionDenied) do
|
23
|
-
Fauna::Resource.create('classes/posts', @attributes)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_token_context
|
30
|
-
Fauna::Client.context(@server_connection) do
|
31
|
-
Fauna::Client.post('users', @attributes)
|
32
|
-
end
|
33
|
-
|
34
|
-
Fauna::Client.context(@client_connection) do
|
35
|
-
@token = Fauna::Client.post('tokens', @attributes)
|
36
|
-
end
|
37
|
-
|
38
|
-
Fauna::Client.context(Fauna::Connection.new(:secret => @token['secret'], :domain => @server_connection.domain, :scheme => @server_connection.scheme, :port => @server_connection.port)) do
|
39
|
-
user = Fauna::Client.get(@token['user'])
|
40
|
-
Fauna::Client.delete(user['ref'])
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_caching_1
|
45
|
-
Fauna::Client.context(@server_connection) do
|
46
|
-
user = Fauna::Client.post('users', @attributes)
|
47
|
-
@server_connection.expects(:get).never
|
48
|
-
Fauna::Client.get(user['ref'])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_caching_2
|
53
|
-
Fauna::Client.context(@client_connection) do
|
54
|
-
user = Fauna::Client.post('users', @attributes)
|
55
|
-
|
56
|
-
Fauna::Client.context(@server_connection) do
|
57
|
-
Fauna::Client.get(user['ref'])
|
58
|
-
@server_connection.expects(:get).never
|
59
|
-
Fauna::Client.get(user['ref'])
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
data/test/connection_test.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class ConnectionTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
super
|
6
|
-
@attributes = { 'name' => 'Arawn', 'email' => email, 'password' => password }
|
7
|
-
end
|
8
|
-
|
9
|
-
def test_get
|
10
|
-
@server_connection.get('users/instances')
|
11
|
-
end
|
12
|
-
|
13
|
-
def test_get_with_invalid_key
|
14
|
-
connection = Fauna::Connection.new(:secret => 'bad_key', :domain => @server_connection.domain, :scheme => @server_connection.scheme, :port => @server_connection.port)
|
15
|
-
assert_raises(Fauna::Connection::Unauthorized) do
|
16
|
-
connection.get('users/instances')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_post
|
21
|
-
@client_connection.post('users', @attributes)['resource']
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_put
|
25
|
-
user = @server_connection.post('users', @attributes)['resource']
|
26
|
-
user = @server_connection.put(user['ref'], :data => { :pockets => 2 })['resource']
|
27
|
-
|
28
|
-
assert_equal 2, user['data']['pockets']
|
29
|
-
|
30
|
-
user = @server_connection.put(user['ref'], :data => { :apples => 3 })['resource']
|
31
|
-
|
32
|
-
assert_nil user['data']['pockets']
|
33
|
-
assert_equal 3, user['data']['apples']
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_patch
|
37
|
-
user = @server_connection.post('users', @attributes)['resource']
|
38
|
-
user = @server_connection.patch(user['ref'], :data => { :pockets => 2 })['resource']
|
39
|
-
user = @server_connection.patch(user['ref'], :data => { :apples => 3 })['resource']
|
40
|
-
|
41
|
-
assert_equal 2, user['data']['pockets']
|
42
|
-
assert_equal 3, user['data']['apples']
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_delete
|
46
|
-
user = @server_connection.post('users', @attributes)['resource']
|
47
|
-
@server_connection.delete(user['ref'])
|
48
|
-
assert_raises(Fauna::Connection::NotFound) do
|
49
|
-
@server_connection.get(user['ref'])
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
# def test_retry
|
54
|
-
# class << RestClient::Request
|
55
|
-
# alias __execute__ execute
|
56
|
-
# end
|
57
|
-
|
58
|
-
# class << RestClient::Request
|
59
|
-
# def execute(*args, &block)
|
60
|
-
# alias execute __execute__
|
61
|
-
# raise RestClient::ServerBrokeConnection
|
62
|
-
# end
|
63
|
-
# end
|
64
|
-
# @server_connection.get('users/instances')
|
65
|
-
# end
|
66
|
-
end
|