fauna 1.1.1 → 1.2

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ OTc2NGU4ZGEyZmI5NjNmYzgyNDY5MGM4YWFhYTEwMDg4YmMyNWM5Yw==
5
+ data.tar.gz: !binary |-
6
+ MjFlMGZmNDYyZWNiMDM0ODU5MjkxNTY0NDkzYjQ4ZjA0MmM3ZmM3YQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Y2ZjYWVkMmU3MzY2ZmRhZTY2YjRiNWMzMDA2Yzc5NjkzODJjZTY2YzlmOThk
10
+ NzBkNDQ4ZDVhOWIzYjk5MGQwYjU0MjRiMGMzODllOGQyN2ZhNmFiNGQ5ZjZm
11
+ ZTBjZjI3ZmFhY2NkMDczMjdiM2MxN2NjNTIzMDdmZWZlM2QyMWY=
12
+ data.tar.gz: !binary |-
13
+ YTk2Njk2ODIyMGZmN2NkYjZjZDAyZGJiZWM0NWVkOTFjMGRjZmQ5ZTQ0MTE1
14
+ NjBkN2JkMDdjZDJkNWMzZWJhNTllODNjOWUwY2RmMjdmZmNhOWYwMDkzNWI5
15
+ MzhjNTczNTk1NDE3NzkwZGJhNTgzMjliMTYxODQ0ZjFhMWIwZmY=
Binary file
Binary file
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v1.2. Switch to Typhoeus HTTP client.
2
+
1
3
  v1.1.1 Remove last bit of ORM-ness.
2
4
 
3
5
  v1.1.0 Updates for Fauna 1.1. Remove schema configuration.
data/Manifest CHANGED
@@ -4,6 +4,7 @@ LICENSE
4
4
  Manifest
5
5
  README.md
6
6
  Rakefile
7
+ fauna-ruby.pem
7
8
  fauna.gemspec
8
9
  lib/fauna.rb
9
10
  lib/fauna/cache.rb
@@ -19,6 +20,7 @@ test/class_test.rb
19
20
  test/client_test.rb
20
21
  test/connection_test.rb
21
22
  test/database_test.rb
23
+ test/query_test.rb
22
24
  test/readme_test.rb
23
25
  test/set_test.rb
24
26
  test/test_helper.rb
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fauna
2
2
 
3
- Ruby client for the [Fauna](http://fauna.org) API.
3
+ Experimental Ruby client for [Fauna](http://fauna.org).
4
4
 
5
5
  ## Installation
6
6
 
@@ -36,7 +36,7 @@ All API requests start with an instance of `Fauna::Connection`.
36
36
  Creating a connection requires either a token, a server key, or a
37
37
  client key.
38
38
 
39
- Let's use a server key we got from our [Fauna Cloud console](https://fauna.org/console):
39
+ Let's use a server key we got from our [Fauna Cloud console](https://fauna.org/account/databases):
40
40
 
41
41
  ```ruby
42
42
  server_key = 'ls8AkXLdakAAAALPAJFy3LvQAAGwDRAS_Prjy6O8VQBfQAlZzwAA'
@@ -106,6 +106,20 @@ Fauna::Client.context($fauna) do
106
106
  end
107
107
  ```
108
108
 
109
+ Fauna resources must be created and accessed by ref, i.e.
110
+
111
+ ```ruby
112
+ pig = Fauna::Resource.create 'classes/pigs'
113
+ pig.data['name'] = 'Henwen'
114
+ pig.save
115
+ pig.ref # => 'classes/pigs/42471470493859841'
116
+
117
+ # and later...
118
+
119
+ pig = Fauna::Resource.find 'classes/pigs/42471470493859841'
120
+ # do something with this pig...
121
+ ````
122
+
109
123
  ## Rails Usage
110
124
 
111
125
  Fauna provides a Rails helper that sets up a default context in
@@ -115,7 +129,7 @@ controllers, based on credentials in `config/fauna.yml`:
115
129
  development:
116
130
  email: taran@example.com
117
131
  password: secret
118
- server_key: secret_key
132
+ secret: secret_key
119
133
  test:
120
134
  email: taran@example.com
121
135
  password: secret
@@ -131,12 +145,20 @@ Then, in `config/initializers/fauna.rb`:
131
145
  require "fauna/rails"
132
146
  ```
133
147
 
148
+ ## Running Tests
149
+
150
+ You can run tests against Fauna Cloud. Set the `FAUNA_ROOT_KEY` environment variable to your CGI-escaped email and password, joined by a `:`. Then run `rake`:
151
+
152
+ ```bash
153
+ export FAUNA_ROOT_KEY="test%40fauna.org:secret"
154
+ rake
155
+ ```
156
+
134
157
  ## Further Reading
135
158
 
136
- Please see the Fauna [REST Documentation](https://fauna.org/API) for a
137
- complete API reference, or look in
138
- [`/test`](https://github.com/fauna/fauna-ruby/tree/master/test) for
139
- more examples.
159
+ Please see the Fauna REST Documentation for a complete API reference,
160
+ or look in [`/test`](https://github.com/fauna/fauna-ruby/tree/master/test)
161
+ for more examples.
140
162
 
141
163
  ## Contributing
142
164
 
data/Rakefile CHANGED
@@ -5,7 +5,10 @@ Echoe.new("fauna") do |p|
5
5
  p.project = "fauna"
6
6
  p.summary = "Official Ruby client for the Fauna API."
7
7
  p.retain_gemspec = true
8
- p.dependencies = ["rest-client", "json"]
8
+ p.require_signed
9
+ p.certificate_chain = ["fauna-ruby.pem"]
10
+ p.licenses = ["Mozilla Public License, Version 2.0 (MPL2)"]
11
+ p.dependencies = ["typhoeus", "json"]
9
12
  p.development_dependencies = ["mocha", "echoe", "minitest"]
10
13
  end
11
14
 
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
3
+ MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
4
+ Fw0xMzExMDQyMDI1MDVaFw0xNDExMDQyMDI1MDVaMD0xDTALBgNVBAMMBGV2YW4x
5
+ GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
6
+ IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuG4q2IdTtlc7/IJkWPnbOAFt
7
+ ysKc3XmLHsjeSXXSPdQ1mb2cDXvyDS8TkzjrgDoJ96RR2xrh7bfkHAMJhSVMhsPM
8
+ rnYS7fDs//X1h6fRYBjjhqGeQhCL1xrS5/I4vKb7AjgFnuUbMZ/H0+ic2Ic2zTnZ
9
+ jttSQZ/QOlYyctrYoTzAFdPwL+dOxskOyAmAbtV/pV3owcXpChRT/tphC7u69sOk
10
+ +IjWsMwrBCbEdj/Jmh4a52QntAwPWx4Krt0zm8eV3/UjSObB3BR1pZ/i5IsSLPs1
11
+ lwMA6ywbfxBTP59XcgAyhfV3rRQXb+vjpf7OLuOCJOUIN8GEwb5HNjFo/UVdiwID
12
+ AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUbTCqyydn
13
+ 0Rm6nngf15KtCEMc37swGwYDVR0RBBQwEoEQZXZhbkBjbG91ZGJ1ci5zdDAbBgNV
14
+ HRIEFDASgRBldmFuQGNsb3VkYnVyLnN0MA0GCSqGSIb3DQEBBQUAA4IBAQBggGGb
15
+ 0AoyF0QofzkPImuhN1UF6eG/RdYOHqiUovuRN/9IblyKAaZAIl1mIspfCav8EVwo
16
+ SC6vz4OaIVpS7QdI04oLNHxhmC6C5TTBONtddDl93M+9uWVipD5uVPktcHWG+bKn
17
+ 2L1lUykQXr8ra45TqAUZ/P+Yv76U8kUsVG2HE5gl/CgB5+V1qkpn5M4CADsvSvPA
18
+ qEATZvw+KUzzMCUiVzq+T6lDrrCt+sD3NZlvG4BD2PpQuPtDf1i61DUc+5s2Nwm2
19
+ t4uqNF7swBWS0n40/hmn5u8pT2JVsuwam79GGhJmNfCdPCcCbgphroexRcrwdURX
20
+ ly00Xdf1gDVBxRoR
21
+ -----END CERTIFICATE-----
@@ -1,42 +1,46 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # stub: fauna 1.2 ruby lib
2
3
 
3
4
  Gem::Specification.new do |s|
4
5
  s.name = "fauna"
5
- s.version = "1.1.1"
6
+ s.version = "1.2"
6
7
 
7
8
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
9
  s.authors = ["Fauna, Inc."]
9
- s.date = "2013-08-08"
10
+ s.cert_chain = ["/Users/eweaver/fauna/fauna-ruby/fauna-ruby.pem"]
11
+ s.date = "2013-11-04"
10
12
  s.description = "Official Ruby client for the Fauna API."
11
13
  s.email = ""
12
14
  s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.md", "lib/fauna.rb", "lib/fauna/cache.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/named_resource.rb", "lib/fauna/rails.rb", "lib/fauna/resource.rb", "lib/fauna/set.rb", "lib/fauna/util.rb", "lib/tasks/fauna.rake"]
13
- s.files = ["CHANGELOG", "Gemfile", "LICENSE", "Manifest", "README.md", "Rakefile", "fauna.gemspec", "lib/fauna.rb", "lib/fauna/cache.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/named_resource.rb", "lib/fauna/rails.rb", "lib/fauna/resource.rb", "lib/fauna/set.rb", "lib/fauna/util.rb", "lib/tasks/fauna.rake", "test/class_test.rb", "test/client_test.rb", "test/connection_test.rb", "test/database_test.rb", "test/readme_test.rb", "test/set_test.rb", "test/test_helper.rb"]
15
+ s.files = ["CHANGELOG", "Gemfile", "LICENSE", "Manifest", "README.md", "Rakefile", "fauna-ruby.pem", "fauna.gemspec", "lib/fauna.rb", "lib/fauna/cache.rb", "lib/fauna/client.rb", "lib/fauna/connection.rb", "lib/fauna/named_resource.rb", "lib/fauna/rails.rb", "lib/fauna/resource.rb", "lib/fauna/set.rb", "lib/fauna/util.rb", "lib/tasks/fauna.rake", "test/class_test.rb", "test/client_test.rb", "test/connection_test.rb", "test/database_test.rb", "test/query_test.rb", "test/readme_test.rb", "test/set_test.rb", "test/test_helper.rb"]
14
16
  s.homepage = "http://fauna.github.com/fauna/"
15
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Fauna", "--main", "README.md"]
17
+ s.licenses = ["Mozilla Public License, Version 2.0 (MPL2)"]
18
+ s.rdoc_options = ["--line-numbers", "--title", "Fauna", "--main", "README.md"]
16
19
  s.require_paths = ["lib"]
17
20
  s.rubyforge_project = "fauna"
18
- s.rubygems_version = "1.8.23"
21
+ s.rubygems_version = "2.1.10"
22
+ s.signing_key = "/Users/eweaver/cloudburst/configuration/gem_certificates/gem-private_key.pem"
19
23
  s.summary = "Official Ruby client for the Fauna API."
20
- s.test_files = ["test/class_test.rb", "test/client_test.rb", "test/connection_test.rb", "test/database_test.rb", "test/readme_test.rb", "test/set_test.rb", "test/test_helper.rb"]
24
+ s.test_files = ["test/class_test.rb", "test/client_test.rb", "test/connection_test.rb", "test/database_test.rb", "test/query_test.rb", "test/readme_test.rb", "test/set_test.rb", "test/test_helper.rb"]
21
25
 
22
26
  if s.respond_to? :specification_version then
23
- s.specification_version = 3
27
+ s.specification_version = 4
24
28
 
25
29
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
26
- s.add_runtime_dependency(%q<rest-client>, [">= 0"])
30
+ s.add_runtime_dependency(%q<typhoeus>, [">= 0"])
27
31
  s.add_runtime_dependency(%q<json>, [">= 0"])
28
32
  s.add_development_dependency(%q<mocha>, [">= 0"])
29
33
  s.add_development_dependency(%q<echoe>, [">= 0"])
30
34
  s.add_development_dependency(%q<minitest>, [">= 0"])
31
35
  else
32
- s.add_dependency(%q<rest-client>, [">= 0"])
36
+ s.add_dependency(%q<typhoeus>, [">= 0"])
33
37
  s.add_dependency(%q<json>, [">= 0"])
34
38
  s.add_dependency(%q<mocha>, [">= 0"])
35
39
  s.add_dependency(%q<echoe>, [">= 0"])
36
40
  s.add_dependency(%q<minitest>, [">= 0"])
37
41
  end
38
42
  else
39
- s.add_dependency(%q<rest-client>, [">= 0"])
43
+ s.add_dependency(%q<typhoeus>, [">= 0"])
40
44
  s.add_dependency(%q<json>, [">= 0"])
41
45
  s.add_dependency(%q<mocha>, [">= 0"])
42
46
  s.add_dependency(%q<echoe>, [">= 0"])
@@ -1,7 +1,8 @@
1
1
  require 'json'
2
2
  require 'logger'
3
3
  require 'uri'
4
- require 'restclient'
4
+ require 'typhoeus'
5
+ require 'cgi'
5
6
 
6
7
  if defined?(Rake)
7
8
  load "#{File.dirname(__FILE__)}/tasks/fauna.rake"
@@ -20,16 +20,16 @@ module Fauna
20
20
  when 200..299
21
21
  res
22
22
  when 400
23
- json = JSON.parse(res)
23
+ json = JSON.parse(res.body)
24
24
  raise BadRequest.new(json['error'], json['param_errors'])
25
25
  when 401
26
- raise Unauthorized, JSON.parse(res)['error']
26
+ raise Unauthorized, JSON.parse(res.body)['error']
27
27
  when 404
28
- raise NotFound, JSON.parse(res)['error']
28
+ raise NotFound, JSON.parse(res.body)['error']
29
29
  when 405
30
- raise NotAllowed, JSON.parse(res)['error']
30
+ raise NotAllowed, JSON.parse(res.body)['error']
31
31
  else
32
- raise NetworkError, res
32
+ raise NetworkError, res.body
33
33
  end
34
34
  end
35
35
 
@@ -39,22 +39,13 @@ module Fauna
39
39
  @logger = params[:logger] || nil
40
40
  @domain = params[:domain] || "rest1.fauna.org"
41
41
  @scheme = params[:scheme] || "https"
42
- @port = params[:port] || 80
42
+ @port = params[:port] || (@scheme == "https" ? 443 : 80)
43
43
 
44
44
  if ENV["FAUNA_DEBUG"]
45
45
  @logger = Logger.new(STDERR)
46
46
  @debug = true
47
47
  end
48
-
49
- # Check credentials from least to most privileged, in case
50
- # multiple were provided
51
- @credentials = if params[:secret]
52
- CGI.escape(params[:secret])
53
- else
54
- raise TypeError
55
- end
56
- rescue TypeError
57
- raise ArgumentError, "Invalid secret."
48
+ @credentials = params[:secret].to_s
58
49
  end
59
50
 
60
51
  def get(ref, query = {})
@@ -80,9 +71,9 @@ module Fauna
80
71
 
81
72
  private
82
73
 
83
- def parse(response)
84
- obj = response.empty? ? {} : JSON.parse(response)
85
- obj.merge! "headers" => Fauna.stringify_keys(response.headers)
74
+ def parse(res)
75
+ obj = res.body.to_s.empty? ? {} : JSON.parse(res.body)
76
+ obj.merge!("headers" => res.headers)
86
77
  obj
87
78
  end
88
79
 
@@ -103,15 +94,12 @@ module Fauna
103
94
  end
104
95
 
105
96
  def execute(action, ref, data = nil, query = nil)
106
- args = { :method => action, :url => url(ref), :headers => {} }
97
+ request = Typhoeus::Request.new(url(ref), :method => action)
98
+ request.options[:params] = query if query.is_a?(Hash)
107
99
 
108
- if query && !query.empty?
109
- args[:headers].merge! :params => query
110
- end
111
-
112
- if data && !data.empty?
113
- args[:headers].merge! :content_type => :json
114
- args.merge! :payload => data.to_json
100
+ if data.is_a?(Hash)
101
+ request.options[:headers] = { "Content-Type" => "application/json;charset=utf-8" }
102
+ request.options[:body] = data.to_json
115
103
  end
116
104
 
117
105
  if @logger
@@ -120,19 +108,17 @@ module Fauna
120
108
  log(4) { "Request JSON: #{JSON.pretty_generate(data)}" } if @debug && data
121
109
 
122
110
  t0, r0 = Process.times, Time.now
111
+ request.run
112
+ t1, r1 = Process.times, Time.now
123
113
 
124
- RestClient::Request.execute(args) do |res, _, _|
125
- t1, r1 = Process.times, Time.now
126
- real = r1.to_f - r0.to_f
127
- cpu = (t1.utime - t0.utime) + (t1.stime - t0.stime) + (t1.cutime - t0.cutime) + (t1.cstime - t0.cstime)
128
- log(4) { ["Response headers: #{JSON.pretty_generate(res.headers)}", "Response JSON: #{res}"] } if @debug
129
- log(4) { "Response (#{res.code}): API processing #{res.headers[:x_http_request_processing_time]}ms, network latency #{((real - cpu)*1000).to_i}ms, local processing #{(cpu*1000).to_i}ms" }
130
-
131
- HANDLER.call(res)
132
- end
114
+ real = r1.to_f - r0.to_f
115
+ cpu = (t1.utime - t0.utime) + (t1.stime - t0.stime) + (t1.cutime - t0.cutime) + (t1.cstime - t0.cstime)
116
+ log(4) { ["Response headers: #{JSON.pretty_generate(request.response.headers)}", "Response JSON: #{request.response.body}"] } if @debug
117
+ log(4) { "Response (#{request.response.code}): API processing #{request.response.headers["X-HTTP-Request-Processing-Time"]}ms, network latency #{((real - cpu)*1000).to_i}ms, local processing #{(cpu*1000).to_i}ms" }
133
118
  else
134
- RestClient::Request.execute(args, &HANDLER)
119
+ request.run
135
120
  end
121
+ HANDLER.call(request.response)
136
122
  end
137
123
 
138
124
  def url(ref)
@@ -9,7 +9,7 @@ if defined?(Rails)
9
9
 
10
10
  @silent = false
11
11
 
12
- CONFIG_FILE = "#{Rails.root}/fauna.yml"
12
+ CONFIG_FILE = "#{Rails.root}/config/fauna.yml"
13
13
  LOCAL_CONFIG_FILE = "#{ENV["HOME"]}/.fauna.yml"
14
14
  APP_NAME = Rails.application.class.name.split("::").first.underscore
15
15
  FIXTURES_DIR = "#{Rails.root}/test/fixtures/fauna"
@@ -23,8 +23,8 @@ if defined?(Rails)
23
23
  end
24
24
 
25
25
  if !@silent
26
- if credentials["server_key"]
27
- STDERR.puts ">> Using Fauna server key #{credentials["server_key"].inspect} for #{APP_NAME.inspect}."
26
+ if credentials["secret"]
27
+ STDERR.puts ">> Using Fauna server key #{credentials["secret"].inspect} for #{APP_NAME.inspect}."
28
28
  else
29
29
  STDERR.puts ">> Using Fauna account #{credentials["email"].inspect} for #{APP_NAME.inspect}."
30
30
  end
@@ -32,18 +32,18 @@ if defined?(Rails)
32
32
  STDERR.puts ">> You can change this in config/fauna.yml or ~/.fauna.yml."
33
33
  end
34
34
 
35
- if credentials["server_key"]
36
- server_key = credentials["server_key"]
35
+ if credentials["secret"]
36
+ secret = credentials["secret"]
37
37
  else
38
38
  self.root_connection = Connection.new(
39
39
  :email => credentials["email"],
40
40
  :password => credentials["password"],
41
41
  :logger => Rails.logger)
42
42
 
43
- server_key = root_connection.post("keys", "role" => "server")["resource"]["key"]
43
+ secret = root_connection.post("keys", "role" => "server")["resource"]["key"]
44
44
  end
45
45
 
46
- self.connection = Connection.new(server_key: server_key, logger: Rails.logger)
46
+ self.connection = Connection.new(secret: secret, logger: Rails.logger)
47
47
  else
48
48
  if !@silent
49
49
  STDERR.puts ">> Fauna account not configured. You can add one in config/fauna.yml."
@@ -54,6 +54,17 @@ module Fauna
54
54
  EventsPage.find("#{ref}/events", {}, pagination)
55
55
  end
56
56
 
57
+ def new_event(action, time)
58
+ if persisted?
59
+ Fauna::Event.new(
60
+ 'resource' => ref,
61
+ 'set' => ref,
62
+ 'action' => action,
63
+ 'ts' => Fauna.usecs_from_time(time)
64
+ )
65
+ end
66
+ end
67
+
57
68
  def set(name)
58
69
  CustomSet.new("#{ref}/sets/#{CGI.escape(name)}")
59
70
  end
@@ -60,31 +60,42 @@ module Fauna
60
60
  end
61
61
 
62
62
  def param_strings
63
+ if @function == 'match'
64
+ # Escape strings for match values
65
+ @params = @params[0..1] + @params[2..-1].map do |p|
66
+ if p.is_a?(String)
67
+ p.inspect
68
+ else
69
+ p
70
+ end
71
+ end
72
+ end
73
+
63
74
  @param_strings ||= @params.map do |p|
64
75
  if p.respond_to? :expr
65
76
  p.expr
66
77
  elsif p.respond_to? :ref
67
78
  p.ref
68
79
  else
69
- p
80
+ p.to_s
70
81
  end
71
82
  end
72
83
  end
73
84
 
74
85
  def expr
75
- @expr ||= "#{@function}(#{param_strings.join ','})"
86
+ @expr ||= "#{@function}(#{param_strings.join(',')})"
76
87
  end
77
88
 
78
89
  def ref
79
- "query?q=#{expr}"
90
+ "queries?q=#{expr}"
80
91
  end
81
92
 
82
93
  def page(pagination = {})
83
- SetPage.find('query', { 'q' => expr }, pagination)
94
+ SetPage.find('queries', { 'q' => expr }, pagination)
84
95
  end
85
96
 
86
97
  def events(pagination = {})
87
- EventsPage.find("query", { 'q' => "events(#{expr})" }, pagination)
98
+ EventsPage.find('queries', { 'q' => "events(#{expr})" }, pagination)
88
99
  end
89
100
  end
90
101
 
@@ -96,34 +107,37 @@ module Fauna
96
107
  def events(pagination = {})
97
108
  query = param_strings.first
98
109
  subqueries = param_strings.drop(1).join ','
99
- EventsPage.find("query", { 'q' => "each(events(#{query}),#{subqueries})" }, pagination)
110
+ EventsPage.find('queries', { 'q' => "each(events(#{query}),#{subqueries})" }, pagination)
100
111
  end
101
112
  end
102
113
 
103
114
  class CustomSet < Set
104
- def add(resource)
105
- self.class.add(self, resource)
115
+ def add(resource, time = nil)
116
+ self.class.add(self, resource, time)
106
117
  end
107
118
 
108
- def remove(resource)
109
- self.class.remove(self, resource)
119
+ def remove(resource, time = nil)
120
+ self.class.remove(self, resource, time)
110
121
  end
111
122
 
112
- def self.add(set, resource)
123
+ def self.add(set, resource, time = nil)
113
124
  set = set.ref if set.respond_to? :ref
114
125
  resource = resource.ref if resource.respond_to? :ref
115
- Fauna::Client.put("#{set}/#{resource}")
126
+ event = time ? "/events/#{Fauna.usecs_from_time(time)}/create" : ''
127
+ Fauna::Client.put("#{set}/#{resource}#{event}")
116
128
  end
117
129
 
118
- def self.remove(set, resource)
130
+ def self.remove(set, resource, time = nil)
119
131
  set = set.ref if set.respond_to? :ref
120
132
  resource = resource.ref if resource.respond_to? :ref
121
- Fauna::Client.delete("#{set}/#{resource}")
133
+ event = time ? "/events/#{Fauna.usecs_from_time(time)}/delete" : ''
134
+ Fauna::Client.put("#{set}/#{resource}#{event}")
122
135
  end
123
136
  end
124
137
 
125
138
  class SetPage < Fauna::Resource
126
139
  include Enumerable
140
+ undef :count
127
141
 
128
142
  def refs
129
143
  @refs ||= struct['resources']
@@ -143,6 +157,7 @@ module Fauna
143
157
 
144
158
  class EventsPage < Fauna::Resource
145
159
  include Enumerable
160
+ undef :count
146
161
 
147
162
  def events
148
163
  @events ||= struct['events'].map { |e| Event.new(e) }
@@ -165,6 +180,18 @@ module Fauna
165
180
  @attrs = attrs
166
181
  end
167
182
 
183
+ def ref
184
+ "#{resource}/events/#{@attrs['ts']}/#{action}"
185
+ end
186
+
187
+ def event_ref
188
+ if set == resource
189
+ "#{resource}/events/#{@attrs['ts']}/#{action}"
190
+ else
191
+ "#{set}/#{resource}/events/#{@attrs['ts']}/#{action}"
192
+ end
193
+ end
194
+
168
195
  def ts
169
196
  Fauna.time_from_usecs(@attrs['ts'])
170
197
  end
@@ -180,5 +207,17 @@ module Fauna
180
207
  def action
181
208
  @attrs['action']
182
209
  end
210
+
211
+ def save
212
+ Fauna::Client.put(event_ref) if editable?
213
+ end
214
+
215
+ def delete
216
+ Fauna::Client.delete(event_ref) if editable?
217
+ end
218
+
219
+ def editable?
220
+ ['create', 'delete'].include? action
221
+ end
183
222
  end
184
223
  end
@@ -1,14 +1,4 @@
1
1
  module Fauna
2
- def self.stringify_keys!(hash)
3
- hash.keys.each do |k|
4
- hash[k.to_s] = hash.delete k
5
- end
6
- end
7
-
8
- def self.stringify_keys(hash)
9
- stringify_keys!(hash.dup)
10
- end
11
-
12
2
  def self.time_from_usecs(microseconds)
13
3
  Time.at(microseconds/1_000_000, microseconds % 1_000_000)
14
4
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../test_helper', __FILE__)
2
2
 
3
- class InstanceTest < MiniTest::Unit::TestCase
3
+ class ClassTest < MiniTest::Unit::TestCase
4
4
 
5
5
  def setup
6
6
  super
@@ -42,13 +42,6 @@ class InstanceTest < MiniTest::Unit::TestCase
42
42
  assert pig1.persisted?
43
43
  end
44
44
 
45
- def test_find_by_constraint
46
- pig = Fauna::Resource.create 'classes/pigs', :constraints => { :name => "the pig" }
47
- pig1 = Fauna::Resource.find('classes/pigs/constraints/name/the%20pig')
48
- assert_equal pig.ref, pig1.ref
49
- assert pig1.persisted?
50
- end
51
-
52
45
  def test_delete
53
46
  pig = Fauna::Resource.create 'classes/pigs'
54
47
  pig.delete
@@ -62,23 +55,4 @@ class InstanceTest < MiniTest::Unit::TestCase
62
55
  pig = Fauna::Resource.new 'classes/pigs'
63
56
  assert_nil pig.ts
64
57
  end
65
-
66
- def test_ts_assignment
67
- time = Time.at(0)
68
- pig = Fauna::Resource.create 'classes/pigs'
69
- pig.ts = time
70
-
71
- Fauna::Client.context(@server_connection) do
72
- pig2 = Fauna::Resource.find(pig.ref)
73
- assert(time != pig2.ts)
74
- end
75
-
76
- pig.save
77
-
78
- Fauna::Client.context(@server_connection) do
79
- pig3 = Fauna::Resource.find(pig.ref)
80
- # Waiting on server support for timestamp overrides
81
- # assert_equal time, pig3.ts
82
- end
83
- end
84
58
  end
@@ -34,4 +34,18 @@ class ConnectionTest < MiniTest::Unit::TestCase
34
34
  @server_connection.get(user['ref'])
35
35
  end
36
36
  end
37
+
38
+ # def test_retry
39
+ # class << RestClient::Request
40
+ # alias __execute__ execute
41
+ # end
42
+
43
+ # class << RestClient::Request
44
+ # def execute(*args, &block)
45
+ # alias execute __execute__
46
+ # raise RestClient::ServerBrokeConnection
47
+ # end
48
+ # end
49
+ # @server_connection.get("users/instances")
50
+ # end
37
51
  end
@@ -10,26 +10,28 @@ class DatabaseTest < MiniTest::Unit::TestCase
10
10
  end
11
11
  end
12
12
 
13
- def test_create
14
- assert_raises(Fauna::Connection::Unauthorized) do
15
- @model.save
13
+ def test_get
14
+ assert_raises(Fauna::Connection::NotFound) do
15
+ Fauna::Resource.find("databases/fauna-ruby-test")
16
+ end
17
+ Fauna::Client.context(@root_connection) do
18
+ Fauna::Resource.find("databases/fauna-ruby-test")
19
+ Fauna::Resource.find("databases/fauna-ruby-test2")
16
20
  end
17
21
  end
18
22
 
19
- def test_self
20
- database = Fauna::Resource.find('databases/self')
21
- assert_equal "databases/fauna-ruby-test", database.ref
22
-
23
- assert_raises(Fauna::Connection::BadRequest) do
24
- Fauna::Client.context(@root_connection) do
25
- Fauna::Resource.find('databases/self')
26
- end
23
+ def test_create
24
+ assert_raises(Fauna::Connection::NotFound) do
25
+ @model.save
26
+ end
27
+ Fauna::Client.context(@root_connection) do
28
+ @model.save
27
29
  end
28
30
  end
29
31
 
30
32
  def test_destroy
31
- assert_raises(Fauna::Connection::Unauthorized) do
32
- Fauna::Resource.find('databases/self').delete
33
+ assert_raises(Fauna::Connection::NotFound) do
34
+ @model.delete
33
35
  end
34
36
  Fauna::Client.context(@root_connection) do
35
37
  @model.delete
@@ -0,0 +1,44 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ # TODO use association_test classes
4
+
5
+ class QueryTest < MiniTest::Unit::TestCase
6
+
7
+ def setup
8
+ super
9
+ @model = Fauna::Resource.create 'classes/message_boards'
10
+ @posts_set = @model.set 'posts'
11
+ @posts = []
12
+ @comments = []
13
+
14
+ 3.times do |i|
15
+ post = Fauna::Resource.create(
16
+ 'classes/posts',
17
+ { :data =>
18
+ { :topic => "The Horned King" } })
19
+ @posts << post
20
+ @posts_set.add(post)
21
+ 3.times do |j|
22
+ comment = Fauna::Resource.create(
23
+ 'classes/comments',
24
+ { :data =>
25
+ { :text => "Do not show the Horned King the whereabouts of the Black Cauldron!" } })
26
+ @comments << comment
27
+ Fauna::CustomSet.new("#{post.ref}/sets/comments").add(comment)
28
+ end
29
+ end
30
+ end
31
+
32
+ def test_join
33
+ query = Fauna::Set.join @posts_set, '_/sets/comments'
34
+ assert_equal 9, query.page.size
35
+ @comments.flatten.each do |comment|
36
+ assert query.page.include? comment.ref
37
+ end
38
+ end
39
+
40
+ def test_match
41
+ query = Fauna::Set.match 'classes/posts', 'data.topic', 'The Horned King'
42
+ assert query.page.size > 1
43
+ end
44
+ end
@@ -14,6 +14,7 @@ class SetTest < MiniTest::Unit::TestCase
14
14
  page = @posts.page
15
15
  assert_equal "#{@model.ref}/sets/posts", page.ref
16
16
  assert_equal 0, page.refs.size
17
+ assert_equal 0, page.count
17
18
  end
18
19
 
19
20
  def test_pagination
@@ -25,6 +26,7 @@ class SetTest < MiniTest::Unit::TestCase
25
26
 
26
27
  page1 = @posts.page(:size => 2)
27
28
  assert_equal 2, page1.refs.size
29
+ assert_equal 5, page1.count
28
30
  page2 = @posts.page(:size => 2, :before => page1.before)
29
31
  assert_equal 2, page2.refs.size
30
32
  page3 = @posts.page(:size => 2, :before => page2.before)
@@ -36,6 +38,7 @@ class SetTest < MiniTest::Unit::TestCase
36
38
  assert_equal 2, page5.refs.size
37
39
  page6 = @posts.page(:size => 2, :after => page5.after)
38
40
  assert_equal 1, page6.refs.size
41
+ assert_equal 5, page6.count
39
42
  end
40
43
 
41
44
  def test_any
@@ -66,29 +69,4 @@ class SetTest < MiniTest::Unit::TestCase
66
69
  @posts.add(post)
67
70
  assert_equal [post.ref], @posts.page.refs
68
71
  end
69
-
70
- def test_event_set_query
71
- posts = (1..3).map do |i|
72
- Fauna::Resource.create('classes/posts').tap do |p|
73
- @posts.add(p)
74
- end
75
- end
76
-
77
- comments = posts.map do |p|
78
- (1..3).map do |i|
79
- Fauna::Resource.create('classes/comments').tap do |c|
80
- comments = Fauna::CustomSet.new("#{p.ref}/sets/comments")
81
- comments.add(c)
82
- end
83
- end
84
- end
85
-
86
- q = Fauna::Set.join(@posts, 'sets/comments')
87
-
88
- assert_equal 9, q.page.size
89
-
90
- comments.flatten.each do |c|
91
- assert q.page.include?(c.ref)
92
- end
93
- end
94
72
  end
@@ -7,16 +7,16 @@ require "fauna"
7
7
  require "securerandom"
8
8
  require "mocha/setup"
9
9
 
10
- FAUNA_ROOTKEY = ENV["FAUNA_ROOTKEY"]
10
+ FAUNA_ROOT_KEY = ENV["FAUNA_ROOT_KEY"]
11
11
  FAUNA_DOMAIN = ENV["FAUNA_DOMAIN"]
12
12
  FAUNA_SCHEME = ENV["FAUNA_SCHEME"]
13
13
  FAUNA_PORT = ENV["FAUNA_PORT"]
14
14
 
15
- if !(FAUNA_ROOTKEY && FAUNA_DOMAIN && FAUNA_SCHEME && FAUNA_PORT)
16
- raise "FAUNA_ROOTKEY, FAUNA_DOMAIN, FAUNA_SCHEME and FAUNA_PORT must be defined in your environment to run tests."
15
+ if !FAUNA_ROOT_KEY
16
+ raise "FAUNA_ROOT_KEY must be defined in your environment to run tests."
17
17
  end
18
18
 
19
- ROOT_CONNECTION = Fauna::Connection.new(:secret => FAUNA_ROOTKEY, :domain => FAUNA_DOMAIN, :scheme => FAUNA_SCHEME, :port => FAUNA_PORT)
19
+ ROOT_CONNECTION = Fauna::Connection.new(:secret => FAUNA_ROOT_KEY, :domain => FAUNA_DOMAIN, :scheme => FAUNA_SCHEME, :port => FAUNA_PORT)
20
20
 
21
21
  Fauna::Client.context(ROOT_CONNECTION) do
22
22
  Fauna::Resource.new('databases', :name => "fauna-ruby-test").delete rescue nil
@@ -38,6 +38,11 @@ Fauna::Client.context(SERVER_CONNECTION) do
38
38
  Fauna::Resource.create 'classes', :name => 'message_boards'
39
39
  Fauna::Resource.create 'classes', :name => 'posts'
40
40
  Fauna::Resource.create 'classes', :name => 'comments'
41
+
42
+ # Fixture for readme_test
43
+ pig = Fauna::Resource.new('classes/pigs/42471470493859841')
44
+ pig.ref = 'classes/pigs/42471470493859841'
45
+ pig.save
41
46
  end
42
47
 
43
48
  # test harness
metadata CHANGED
@@ -1,20 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fauna
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
5
- prerelease:
4
+ version: '1.2'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Fauna, Inc.
9
8
  autorequire:
10
9
  bindir: bin
11
- cert_chain: []
12
- date: 2013-08-08 00:00:00.000000000 Z
10
+ cert_chain:
11
+ - !binary |-
12
+ LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhRENDQWxDZ0F3SUJB
13
+ Z0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREE5TVEwd0N3WURWUVFEREFSbGRt
14
+ RnUKTVJnd0ZnWUtDWkltaVpQeUxHUUJHUllJWTJ4dmRXUmlkWEl4RWpBUUJn
15
+ b0praWFKay9Jc1pBRVpGZ0p6ZERBZQpGdzB4TXpFeE1EUXlNREkxTURWYUZ3
16
+ MHhOREV4TURReU1ESTFNRFZhTUQweERUQUxCZ05WQkFNTUJHVjJZVzR4CkdE
17
+ QVdCZ29Ka2lhSmsvSXNaQUVaRmdoamJHOTFaR0oxY2pFU01CQUdDZ21TSm9t
18
+ VDhpeGtBUmtXQW5OME1JSUIKSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4
19
+ QU1JSUJDZ0tDQVFFQXVHNHEySWRUdGxjNy9JSmtXUG5iT0FGdAp5c0tjM1ht
20
+ TEhzamVTWFhTUGRRMW1iMmNEWHZ5RFM4VGt6anJnRG9KOTZSUjJ4cmg3YmZr
21
+ SEFNSmhTVk1oc1BNCnJuWVM3ZkRzLy9YMWg2ZlJZQmpqaHFHZVFoQ0wxeHJT
22
+ NS9JNHZLYjdBamdGbnVVYk1aL0gwK2ljMkljMnpUbloKanR0U1FaL1FPbFl5
23
+ Y3RyWW9UekFGZFB3TCtkT3hza095QW1BYnRWL3BWM293Y1hwQ2hSVC90cGhD
24
+ N3U2OXNPaworSWpXc013ckJDYkVkai9KbWg0YTUyUW50QXdQV3g0S3J0MHpt
25
+ OGVWMy9ValNPYkIzQlIxcFovaTVJc1NMUHMxCmx3TUE2eXdiZnhCVFA1OVhj
26
+ Z0F5aGZWM3JSUVhiK3ZqcGY3T0x1T0NKT1VJTjhHRXdiNUhOakZvL1VWZGl3
27
+ SUQKQVFBQm8zTXdjVEFKQmdOVkhSTUVBakFBTUFzR0ExVWREd1FFQXdJRXNE
28
+ QWRCZ05WSFE0RUZnUVViVENxeXlkbgowUm02bm5nZjE1S3RDRU1jMzdzd0d3
29
+ WURWUjBSQkJRd0VvRVFaWFpoYmtCamJHOTFaR0oxY2k1emREQWJCZ05WCkhS
30
+ SUVGREFTZ1JCbGRtRnVRR05zYjNWa1luVnlMbk4wTUEwR0NTcUdTSWIzRFFF
31
+ QkJRVUFBNElCQVFCZ2dHR2IKMEFveUYwUW9memtQSW11aE4xVUY2ZUcvUmRZ
32
+ T0hxaVVvdnVSTi85SWJseUtBYVpBSWwxbUlzcGZDYXY4RVZ3bwpTQzZ2ejRP
33
+ YUlWcFM3UWRJMDRvTE5IeGhtQzZDNVRUQk9OdGRkRGw5M00rOXVXVmlwRDV1
34
+ VlBrdGNIV0crYktuCjJMMWxVeWtRWHI4cmE0NVRxQVVaL1ArWXY3NlU4a1Vz
35
+ VkcySEU1Z2wvQ2dCNStWMXFrcG41TTRDQURzdlN2UEEKcUVBVFp2dytLVXp6
36
+ TUNVaVZ6cStUNmxEcnJDdCtzRDNOWmx2RzRCRDJQcFF1UHREZjFpNjFEVWMr
37
+ NXMyTndtMgp0NHVxTkY3c3dCV1MwbjQwL2htbjV1OHBUMkpWc3V3YW03OUdH
38
+ aEptTmZDZFBDY0NiZ3Bocm9leFJjcndkVVJYCmx5MDBYZGYxZ0RWQnhSb1IK
39
+ LS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
40
+ date: 2013-11-04 00:00:00.000000000 Z
13
41
  dependencies:
14
42
  - !ruby/object:Gem::Dependency
15
- name: rest-client
43
+ name: typhoeus
16
44
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
45
  requirements:
19
46
  - - ! '>='
20
47
  - !ruby/object:Gem::Version
@@ -22,7 +49,6 @@ dependencies:
22
49
  type: :runtime
23
50
  prerelease: false
24
51
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
52
  requirements:
27
53
  - - ! '>='
28
54
  - !ruby/object:Gem::Version
@@ -30,7 +56,6 @@ dependencies:
30
56
  - !ruby/object:Gem::Dependency
31
57
  name: json
32
58
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
59
  requirements:
35
60
  - - ! '>='
36
61
  - !ruby/object:Gem::Version
@@ -38,7 +63,6 @@ dependencies:
38
63
  type: :runtime
39
64
  prerelease: false
40
65
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
66
  requirements:
43
67
  - - ! '>='
44
68
  - !ruby/object:Gem::Version
@@ -46,7 +70,6 @@ dependencies:
46
70
  - !ruby/object:Gem::Dependency
47
71
  name: mocha
48
72
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
73
  requirements:
51
74
  - - ! '>='
52
75
  - !ruby/object:Gem::Version
@@ -54,7 +77,6 @@ dependencies:
54
77
  type: :development
55
78
  prerelease: false
56
79
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
80
  requirements:
59
81
  - - ! '>='
60
82
  - !ruby/object:Gem::Version
@@ -62,7 +84,6 @@ dependencies:
62
84
  - !ruby/object:Gem::Dependency
63
85
  name: echoe
64
86
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
87
  requirements:
67
88
  - - ! '>='
68
89
  - !ruby/object:Gem::Version
@@ -70,7 +91,6 @@ dependencies:
70
91
  type: :development
71
92
  prerelease: false
72
93
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
94
  requirements:
75
95
  - - ! '>='
76
96
  - !ruby/object:Gem::Version
@@ -78,7 +98,6 @@ dependencies:
78
98
  - !ruby/object:Gem::Dependency
79
99
  name: minitest
80
100
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
101
  requirements:
83
102
  - - ! '>='
84
103
  - !ruby/object:Gem::Version
@@ -86,7 +105,6 @@ dependencies:
86
105
  type: :development
87
106
  prerelease: false
88
107
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
108
  requirements:
91
109
  - - ! '>='
92
110
  - !ruby/object:Gem::Version
@@ -116,6 +134,7 @@ files:
116
134
  - Manifest
117
135
  - README.md
118
136
  - Rakefile
137
+ - fauna-ruby.pem
119
138
  - fauna.gemspec
120
139
  - lib/fauna.rb
121
140
  - lib/fauna/cache.rb
@@ -131,15 +150,17 @@ files:
131
150
  - test/client_test.rb
132
151
  - test/connection_test.rb
133
152
  - test/database_test.rb
153
+ - test/query_test.rb
134
154
  - test/readme_test.rb
135
155
  - test/set_test.rb
136
156
  - test/test_helper.rb
137
157
  homepage: http://fauna.github.com/fauna/
138
- licenses: []
158
+ licenses:
159
+ - Mozilla Public License, Version 2.0 (MPL2)
160
+ metadata: {}
139
161
  post_install_message:
140
162
  rdoc_options:
141
163
  - --line-numbers
142
- - --inline-source
143
164
  - --title
144
165
  - Fauna
145
166
  - --main
@@ -147,28 +168,27 @@ rdoc_options:
147
168
  require_paths:
148
169
  - lib
149
170
  required_ruby_version: !ruby/object:Gem::Requirement
150
- none: false
151
171
  requirements:
152
172
  - - ! '>='
153
173
  - !ruby/object:Gem::Version
154
174
  version: '0'
155
175
  required_rubygems_version: !ruby/object:Gem::Requirement
156
- none: false
157
176
  requirements:
158
177
  - - ! '>='
159
178
  - !ruby/object:Gem::Version
160
179
  version: '1.2'
161
180
  requirements: []
162
181
  rubyforge_project: fauna
163
- rubygems_version: 1.8.23
182
+ rubygems_version: 2.1.10
164
183
  signing_key:
165
- specification_version: 3
184
+ specification_version: 4
166
185
  summary: Official Ruby client for the Fauna API.
167
186
  test_files:
168
187
  - test/class_test.rb
169
188
  - test/client_test.rb
170
189
  - test/connection_test.rb
171
190
  - test/database_test.rb
191
+ - test/query_test.rb
172
192
  - test/readme_test.rb
173
193
  - test/set_test.rb
174
194
  - test/test_helper.rb
Binary file