fauna 1.1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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