fauna 1.3.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZjI4NGIwZGEyZWIyYzJiZmY5Y2UxMWMzM2QyZDg2YTNjMjc5NGFmMg==
5
- data.tar.gz: !binary |-
6
- NTQyNTE5MTdlOGY2YWZmMTFiNTQyYTE4OWZiZDA1YTU3NjYyYzk4NA==
2
+ SHA1:
3
+ metadata.gz: 9179efc5b2e53c99b6d398de61902fd963fefea7
4
+ data.tar.gz: cfbee10e91d3cdfe4baabc212b34cfd1ae348ea9
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzE5MTU4NGU0NWJlNzU3ZWE2NjQ2NzI1N2M3NGVjYmViOTNmZmEyN2NkMjll
10
- YmM1MGMxOTBhOTNkYWUyNGNkZTJiOTg3YzgxNmUzMWQ0NzU1MWJlZWJkMGI0
11
- ZDNjNjM4NDJlNjU0YTQ3MDU5OWVlMDU1Mzc3NGY5Y2IyN2MyZGU=
12
- data.tar.gz: !binary |-
13
- NDlkYzBmNGY5NWU2YmRiODA0YTE1NGNiZWUyMTgxMjAwYWJlNjNmOWFhZTJm
14
- OThlY2JiNjA0YzY0ZTY5OGYzN2M2NWJkNDNjYWZiZDNlNTQ1ZDgyZDZmNzNh
15
- NTc1NTMyZDRjMTBmYzk4MDJlYTIzZDllMDg1ZWVlNzI0ZjY0ZWI=
6
+ metadata.gz: c143182304816bde8ed2b057cfd9e0c0a267e382e810c7c651139d7efcfe2aedee343fdae75c76816a4dfe90a775d6cdf921f295cc94f7c7241038fa06ed2587
7
+ data.tar.gz: 534a5305cacdc340f870f975435c8a69cd0aa3647ddfbf4324226d3171f3ab0f16f1280e96e4551fc1cde9b6ee01691933a016f122be7ec25ecc658c802ae150
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v2.0.0 Complete rewrite for API 2.0. Not backwards compatible with the old client or api.
2
+
1
3
  v1.3.4 Index support.
2
4
 
3
5
  v1.3.3 Fix #61.
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gem 'rake'
4
- gem 'jruby-openssl', :platform => :jruby
4
+ gem 'jruby-openssl', platform: :jruby
5
5
 
6
6
  gemspec
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2013 Fauna, Inc.
1
+ Copyright 2015 Fauna, Inc.
2
2
 
3
3
  Licensed under the Mozilla Public License, Version 2.0 (the "License"); you may
4
4
  not use this software except in compliance with the License. You may obtain a
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
- # Fauna
1
+ # FaunaDB
2
2
 
3
- Experimental Ruby client for [Fauna](http://fauna.org).
3
+ Ruby client for [FaunaDB](https://faunadb.com).
4
4
 
5
5
  ## Installation
6
6
 
7
- The Fauna ruby client is distributed as a gem. Install it via:
7
+ The FaunaDB ruby client is distributed as a gem. Install it via:
8
8
 
9
9
  $ gem install fauna
10
10
 
@@ -18,145 +18,108 @@ And then execute:
18
18
 
19
19
  ## Compatibility
20
20
 
21
- Tested and compatible with MRI 1.9.3. Other Rubies may also work.
21
+ Tested and compatible with the following ruby versions:
22
+
23
+ * MRI 1.9.3
24
+ * MRI 2.2.3
25
+ * Jruby 1.7.19
22
26
 
23
27
  ## Basic Usage
24
28
 
25
29
  First, require the gem:
26
30
 
27
31
  ```ruby
28
- require "rubygems"
29
- require "fauna"
32
+ require 'fauna'
30
33
  ```
31
34
 
32
- ### Configuring the API
33
-
34
- All API requests start with an instance of `Fauna::Connection`.
35
+ ### Creating a Client
35
36
 
36
- Creating a connection requires either a token, a server key, or a
37
- client key.
37
+ All API requests pass through a `Fauna::Client`. Creating a client
38
+ requires either an admin key, server key, client key, or a token.
38
39
 
39
40
  ```ruby
40
41
  server_key = 'ls8AkXLdakAAAALPAJFy3LvQAAGwDRAS_Prjy6O8VQBfQAlZzwAA'
41
42
  ```
42
- Now we can make a global database-level connection:
43
-
44
- ```ruby
45
- $fauna = Fauna::Connection.new(secret: server_key)
46
- ```
47
43
 
48
- You can optionally configure a `logger` on the connection to ease
49
- debugging:
44
+ Now we can make a database-level client:
50
45
 
51
46
  ```ruby
52
- require "logger"
53
- $fauna = Fauna::Connection.new(
54
- secret: server_key,
55
- logger: Logger.new(STDERR))
47
+ $fauna = Fauna::Client.new(secret: server_key)
56
48
  ```
57
49
 
58
- ### Client Contexts
59
-
60
- The easiest way to work with a connection is to open up a *client
61
- context*, and then manipulate resources within that context:
50
+ You can optionally configure an `observer` on the client. To ease
51
+ debugging, we provide a simple logging observer at
52
+ `Fauna::ClientLogger.logger`, which you can configure as such:
62
53
 
63
54
  ```ruby
64
- Fauna::Client.context($fauna) do
65
- user = Fauna::Resource.create('users', email: "taran@example.com")
66
- user.data["name"] = "Taran"
67
- user.data["profession"] = "Pigkeeper"
68
- user.save
69
- user.delete
70
- end
71
- ```
55
+ require 'logger'
56
+ logger = Logger.new(STDERR)
57
+ observer = Fauna::ClientLogger.logger { |log| logger.debug(log) }
72
58
 
73
- By working within a context, not only are you able to use a more
74
- convienient, object-oriented API, you also gain the advantage of
75
- in-process caching.
76
-
77
- Within a context block, requests for a resource that has already been
78
- loaded via a previous request will be returned from the cache and no
79
- query will be issued. This substantially lowers network overhead,
80
- since Fauna makes an effort to return related resources as part of
81
- every response.
59
+ $fauna = Fauna::Client.new(
60
+ secret: server_key,
61
+ observer: observer)
62
+ ```
82
63
 
83
- ### Fauna::Resource
64
+ ### Using the Client
84
65
 
85
- All instances of fauna classes have built-in accessors for common
86
- fields:
66
+ Now that we have a client, we can start performing queries:
87
67
 
88
68
  ```ruby
89
- Fauna::Client.context($fauna) do
90
- user = Fauna::Resource.create('users', constraints: {"username" => "taran77"})
69
+ # Create a class
70
+ $fauna.query { create ref('classes'), name: 'users' }
91
71
 
92
- # fields
93
- user.ref # => "users/123"
94
- user.ts # => 2013-01-30 13:02:46 -0800
95
- user.deleted? # => false
96
- user.constraints # => {"username" => "taran77"}
97
-
98
- # data and references
99
- user.data # => {}
100
- user.references # => {}
101
-
102
- # resource events timeline
103
- user.events
72
+ # Create an instance of the class
73
+ taran = $fauna.query do
74
+ create ref('classes/users'), data: { email: 'taran@example.com' }
104
75
  end
105
- ```
106
76
 
107
- Fauna resources must be created and accessed by ref, i.e.
108
-
109
- ```ruby
110
- pig = Fauna::Resource.create 'classes/pigs'
111
- pig.data['name'] = 'Henwen'
112
- pig.save
113
- pig.ref # => 'classes/pigs/42471470493859841'
114
-
115
- # and later...
116
-
117
- pig = Fauna::Resource.find 'classes/pigs/42471470493859841'
118
- # do something with this pig...
119
- ````
120
-
121
- ## Rails Usage
122
-
123
- Fauna provides a Rails helper that sets up a default context in
124
- controllers, based on credentials in `config/fauna.yml`:
125
-
126
- ```yaml
127
- development:
128
- email: taran@example.com
129
- password: secret
130
- secret: secret_key
131
- test:
132
- email: taran@example.com
133
- password: secret
134
- ```
77
+ # Update the instance
78
+ taran = $fauna.query do
79
+ update taran[:ref], data: {
80
+ name: 'Taran',
81
+ profession: 'Pigkeeper'
82
+ }
83
+ end
135
84
 
136
- (In `config/fauna.yml`, if an existing server key is specified, the
137
- email and password can be omitted. If a server key is not
138
- specified, a new one will be created each time the app is started.)
85
+ # Page through a set
86
+ pigkeepers = Fauna::Query.expr { match(ref('indexes/users_by_profession'), 'Pigkeeper') }
87
+ oracles = Fauna::Query.expr { match(ref('indexes/users_by_profession'), 'Oracle') }
139
88
 
140
- Then, in `config/initializers/fauna.rb`:
89
+ $fauna.query { paginate(union(pigkeepers, oracles)) }
141
90
 
142
- ```ruby
143
- require "fauna/rails"
91
+ # Delete the user
92
+ $fauna.query { delete user[:ref] }
144
93
  ```
145
94
 
146
95
  ## Running Tests
147
96
 
148
- 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`:
97
+ You can run tests against FaunaDB Cloud yourself.
98
+ [Create an admin key](https://faunadb.com/account/keys) and set
99
+ `FAUNA_ROOT_KEY` environment variable to it's secret. Then run `rake test`:
149
100
 
150
101
  ```bash
151
- export FAUNA_ROOT_KEY="test%40fauna.org:secret"
152
- rake
102
+ export FAUNA_ROOT_KEY='kqnPAbijGhkgAAC03-36hjCvcTnWf4Pl8w97UE1HeWo'
103
+ rake test
153
104
  ```
154
105
 
106
+ To run a single test, use e.g. `ruby test/client_test.rb`.
107
+
108
+ Coverage is automatically run as part of the tests. After running tests, check
109
+ `coverage/index.html` for the coverage report. If using jruby, use
110
+ `JRUBY_OPTS="--debug" bundle exec rake test` to ensure coverage is generated
111
+ correctly.
112
+
113
+ ## Documenting
114
+
115
+ Use `rake rdoc` to generate documentation.
116
+
155
117
  ## Further Reading
156
118
 
157
- Please see the Fauna REST Documentation for a complete API reference,
158
- or look in [`/test`](https://github.com/fauna/fauna-ruby/tree/master/test)
159
- for more examples.
119
+ Please see the [FaunaDB Documentation](https://faunadb.com/documentation) for
120
+ a complete API reference, or look in
121
+ [`/test`](https://github.com/faunadb/faunadb-ruby/tree/master/test) for more
122
+ examples.
160
123
 
161
124
  ## Contributing
162
125
 
@@ -164,7 +127,7 @@ GitHub pull requests are very welcome.
164
127
 
165
128
  ## LICENSE
166
129
 
167
- Copyright 2013 [Fauna, Inc.](https://fauna.org/)
130
+ Copyright 2016 [Fauna, Inc.](https://faunadb.com/)
168
131
 
169
132
  Licensed under the Mozilla Public License, Version 2.0 (the
170
133
  "License"); you may not use this software except in compliance with
data/Rakefile CHANGED
@@ -1,22 +1,5 @@
1
- require 'echoe'
2
-
3
- Echoe.new('fauna') do |p|
4
- p.author = 'Fauna, Inc.'
5
- p.project = 'fauna'
6
- p.summary = 'Ruby client for the Fauna distributed database.'
7
- p.retain_gemspec = true
8
- p.licenses = ['Mozilla Public License, Version 2.0 (MPL2)']
9
- p.dependencies = ['faraday ~>0.9.0', 'json ~>1.8.0']
10
- p.development_dependencies = ['mocha', 'echoe', 'minitest ~>4.0', 'rubocop']
11
- end
12
-
13
- task :beautify do
14
- require 'ruby-beautify'
15
- Dir['**/*rb'].each do |filename|
16
- s = RBeautify.beautify_string(:ruby, File.read(filename))
17
- File.write(filename, s) unless s.empty?
18
- end
19
- end
1
+ require 'rspec/core/rake_task'
2
+ require 'rdoc/task'
20
3
 
21
4
  begin
22
5
  require 'rubocop/rake_task'
@@ -27,4 +10,13 @@ rescue LoadError
27
10
  end
28
11
  end
29
12
 
30
- task :prerelease => [:manifest, :test, :install]
13
+ RSpec::Core::RakeTask.new(:spec)
14
+
15
+ RDoc::Task.new do |rdoc|
16
+ rdoc.main = 'README.md'
17
+ rdoc.rdoc_dir = 'doc'
18
+ rdoc.rdoc_files.include('README.md', 'lib/fauna.rb', 'lib/fauna/*.rb')
19
+ end
20
+
21
+ task prerelease: [:spec, :install]
22
+ task default: :spec
@@ -1,50 +1,25 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: fauna 1.3.4 ruby lib
2
+ require './lib/fauna/version'
3
3
 
4
4
  Gem::Specification.new do |s|
5
- s.name = "fauna"
6
- s.version = "1.3.4"
5
+ s.name = 'fauna'
6
+ s.version = Fauna::VERSION
7
+ s.author = 'Fauna, Inc.'
8
+ s.email = 'priority@faunadb.com'
9
+ s.summary = 'FaunaDB Ruby client'
10
+ s.description = 'Ruby client for the Fauna distributed database.'
11
+ s.homepage = 'https://github.com/faunadb/faunadb-ruby'
12
+ s.license = 'MPL-2.0'
7
13
 
8
- s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
9
- s.authors = ["Fauna, Inc."]
10
- s.date = "2015-01-14"
11
- s.description = "Ruby client for the Fauna distributed database."
12
- s.email = ""
13
- 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"]
14
- 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/query_test.rb", "test/readme_test.rb", "test/set_test.rb", "test/test_helper.rb"]
15
- s.homepage = "http://fauna.github.com/fauna/"
16
- s.licenses = ["Mozilla Public License, Version 2.0 (MPL2)"]
17
- s.rdoc_options = ["--line-numbers", "--title", "Fauna", "--main", "README.md"]
18
- s.require_paths = ["lib"]
19
- s.rubyforge_project = "fauna"
20
- s.rubygems_version = "2.1.10"
21
- s.summary = "Ruby client for the Fauna distributed database."
22
- 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"]
14
+ s.files = %w(CHANGELOG Gemfile LICENSE README.md Rakefile fauna.gemspec lib/fauna.rb) + Dir.glob('lib/fauna/**') + Dir.glob('spec/**')
15
+ s.extra_rdoc_files = %w(CHANGELOG LICENSE README.md)
16
+ s.rdoc_options = %w(--line-numbers --title Fauna --main README.md)
17
+ s.test_files = Dir.glob('spec/**')
18
+ s.require_paths = ['lib']
23
19
 
24
- if s.respond_to? :specification_version then
25
- s.specification_version = 4
26
-
27
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
- s.add_runtime_dependency(%q<faraday>, ["~> 0.9.0"])
29
- s.add_runtime_dependency(%q<json>, ["~> 1.8.0"])
30
- s.add_development_dependency(%q<mocha>, [">= 0"])
31
- s.add_development_dependency(%q<echoe>, [">= 0"])
32
- s.add_development_dependency(%q<minitest>, ["~> 4.0"])
33
- s.add_development_dependency(%q<rubocop>, [">= 0"])
34
- else
35
- s.add_dependency(%q<faraday>, ["~> 0.9.0"])
36
- s.add_dependency(%q<json>, ["~> 1.8.0"])
37
- s.add_dependency(%q<mocha>, [">= 0"])
38
- s.add_dependency(%q<echoe>, [">= 0"])
39
- s.add_dependency(%q<minitest>, ["~> 4.0"])
40
- s.add_dependency(%q<rubocop>, [">= 0"])
41
- end
42
- else
43
- s.add_dependency(%q<faraday>, ["~> 0.9.0"])
44
- s.add_dependency(%q<json>, ["~> 1.8.0"])
45
- s.add_dependency(%q<mocha>, [">= 0"])
46
- s.add_dependency(%q<echoe>, [">= 0"])
47
- s.add_dependency(%q<minitest>, ["~> 4.0"])
48
- s.add_dependency(%q<rubocop>, [">= 0"])
49
- end
20
+ s.add_runtime_dependency 'faraday', '~> 0.9.0'
21
+ s.add_runtime_dependency 'json', '~> 1.8'
22
+ s.add_development_dependency 'rspec', '~> 3.4'
23
+ s.add_development_dependency 'rubocop', '~> 0.35.0'
24
+ s.add_development_dependency 'coveralls', '~> 0.8.10'
50
25
  end
@@ -4,21 +4,19 @@ require 'uri'
4
4
  require 'faraday'
5
5
  require 'cgi'
6
6
  require 'zlib'
7
+ require 'time'
7
8
 
8
- load "#{File.dirname(__FILE__)}/tasks/fauna.rake" if defined?(Rake)
9
-
10
- module Fauna
11
- class Invalid < RuntimeError
12
- end
13
-
14
- class NotFound < RuntimeError
15
- end
16
- end
9
+ ##
10
+ # Main namespace for the FaunaDB client.
11
+ module Fauna; end
17
12
 
13
+ require 'fauna/version'
14
+ require 'fauna/json'
18
15
  require 'fauna/util'
19
- require 'fauna/connection'
20
- require 'fauna/cache'
16
+ require 'fauna/errors'
21
17
  require 'fauna/client'
22
- require 'fauna/resource'
23
- require 'fauna/named_resource'
24
- require 'fauna/set'
18
+ require 'fauna/client_logger'
19
+ require 'fauna/context'
20
+ require 'fauna/objects'
21
+ require 'fauna/query'
22
+ require 'fauna/request_result'
@@ -1,54 +1,252 @@
1
1
  module Fauna
2
+ ##
3
+ # The Ruby client for FaunaDB.
4
+ #
5
+ # All methods return a converted JSON response.
6
+ # This is a Hash containing Arrays, ints, floats, strings, and other Hashes.
7
+ # Hash keys are always Symbols.
8
+ #
9
+ # Any Ref, SetRef, Time or Date values in it will also be parsed.
10
+ # (So instead of <code>{ "@ref": "classes/frogs/123" }</code>,
11
+ # you will get <code>Fauna::Ref.new("classes/frogs/123")</code>).
2
12
  class Client
3
- def self.context(connection)
4
- push_context(connection)
5
- yield
6
- ensure
7
- pop_context
13
+ # The domain requests will be sent to.
14
+ attr_reader :domain
15
+ # Scheme used when sending requests (either +http+ or +https+).
16
+ attr_reader :scheme
17
+ # Port used when sending requests.
18
+ attr_reader :port
19
+ # An array of the user and pass used for authentication when sending requests.
20
+ attr_reader :credentials
21
+ # Read timeout in seconds.
22
+ attr_reader :read_timeout
23
+ # Open timeout in seconds.
24
+ attr_reader :connection_timeout
25
+ # Callback that will be passed a +RequestResult+ after every completed request.
26
+ attr_reader :observer
27
+ # Faraday adapter in use.
28
+ attr_reader :adapter
29
+
30
+ ##
31
+ # Create a new Client.
32
+ #
33
+ # +params+:: A list of parameters to configure the connection with.
34
+ # +:domain+:: The domain to send requests to.
35
+ # +:scheme+:: Scheme to use when sending requests (either +http+ or +https+).
36
+ # +:port+:: Port to use when sending requests.
37
+ # +:secret+:: Credentials to use when sending requests. User and pass must be separated by a colon.
38
+ # +:read_timeout+:: Read timeout in seconds.
39
+ # +:connection_timeout+:: Open timeout in seconds.
40
+ # +:observer+:: Callback that will be passed a RequestResult after every completed request.
41
+ # +:adapter+:: Faraday[https://github.com/lostisland/faraday] adapter to use. Either can be a symbol for the adapter, or an array of arguments.
42
+ def initialize(params = {})
43
+ @domain = params[:domain] || 'rest.faunadb.com'
44
+ @scheme = params[:scheme] || 'https'
45
+ @port = params[:port] || (scheme == 'https' ? 443 : 80)
46
+ @read_timeout = params[:read_timeout] || 60
47
+ @connection_timeout = params[:connection_timeout] || 60
48
+ @observer = params[:observer]
49
+ @adapter = params[:adapter] || Faraday.default_adapter
50
+ init_credentials(params[:secret])
51
+
52
+ init_connection
8
53
  end
9
54
 
10
- def self.push_context(connection)
11
- stack.push(Fauna::Cache.new(connection))
55
+ ##
56
+ # Create a new client from the existing config with a given secret.
57
+ #
58
+ # +:secret+:: Credentials to use when sending requests. User and pass must be separated by a colon.
59
+ def with_secret(secret)
60
+ with_dup do |client|
61
+ client.send(:init_credentials, secret)
62
+ end
12
63
  end
13
64
 
14
- def self.pop_context
15
- stack.pop
65
+ ##
66
+ # Issues a query to FaunaDB.
67
+ #
68
+ # Queries are built via the Query helpers. See {FaunaDB Query API}[https://faunadb.com/documentation/queries]
69
+ # for information on constructing queries.
70
+ #
71
+ # +expression+:: A query expression
72
+ # +expr_block+:: May be provided instead of expression. Block is used to build an expression with Fauna.query.
73
+ #
74
+ # Example using expression:
75
+ #
76
+ # <code>client.query(Fauna::Query.add(1, 2, Fauna::Query.subtract(3, 2)))</code>
77
+ #
78
+ # Example using block:
79
+ #
80
+ # <code>client.query { add(1, 2, subtract(3, 2)) }</code>
81
+ #
82
+ # Reference: {Executing FaunaDB Queries}[https://faunadb.com/documentation#queries]
83
+ #
84
+ # :category: Query Methods
85
+ def query(expression = nil, &expr_block)
86
+ if expr_block.nil?
87
+ post '', Fauna::Query::Expr.wrap(expression)
88
+ else
89
+ post '', Fauna::Query.expr(&expr_block)
90
+ end
16
91
  end
17
92
 
18
- def self.reset_context
19
- stack = [] # rubocop:disable Lint/UselessAssignment
93
+ ##
94
+ # Performs a +GET+ request for a REST endpoint.
95
+ #
96
+ # +path+:: Path to +GET+.
97
+ # +query+:: Query parameters to append to the path.
98
+ #
99
+ # Reference: {FaunaDB REST API}[https://faunadb.com/documentation/rest]
100
+ #
101
+ # :category: REST Methods
102
+ def get(path, query = {})
103
+ execute(:get, path.to_s, query)
20
104
  end
21
105
 
22
- def self.get(ref, query = {}, pagination = {})
23
- connection.get(ref, query, pagination)
106
+ ##
107
+ # Performs a +POST+ request for a REST endpoint.
108
+ #
109
+ # +path+:: Path to +POST+.
110
+ # +data+:: Data to post as the body. +data+ is automatically converted to JSON.
111
+ #
112
+ # Reference: {FaunaDB REST API}[https://faunadb.com/documentation/rest]
113
+ #
114
+ # :category: REST Methods
115
+ def post(path, data = {})
116
+ execute(:post, path, nil, data)
24
117
  end
25
118
 
26
- def self.post(ref, data = {})
27
- connection.post(ref, data)
119
+ ##
120
+ # Performs a +PUT+ request for a REST endpoint.
121
+ #
122
+ # +path+:: Path to +PUT+.
123
+ # +data+:: Data to post as the body. +data+ is automatically converted to JSON.
124
+ #
125
+ # Reference: {FaunaDB REST API}[https://faunadb.com/documentation/rest]
126
+ #
127
+ # :category: REST Methods
128
+ def put(path, data = {})
129
+ execute(:put, path, nil, data)
28
130
  end
29
131
 
30
- def self.put(ref, data = {})
31
- connection.put(ref, data)
132
+ ##
133
+ # Performs a +PATCH+ request for a REST endpoint.
134
+ #
135
+ # +path+:: Path to +PATCH+.
136
+ # +data+:: Data to post as the body. +data+ is automatically converted to JSON.
137
+ #
138
+ # Reference: {FaunaDB REST API}[https://faunadb.com/documentation/rest]
139
+ #
140
+ # :category: REST Methods
141
+ def patch(path, data = {})
142
+ execute(:patch, path, nil, data)
32
143
  end
33
144
 
34
- def self.patch(ref, data = {})
35
- connection.patch(ref, data)
145
+ ##
146
+ # Performs a +DELETE+ request for a REST endpoint.
147
+ #
148
+ # +path+:: Path to +DELETE+.
149
+ #
150
+ # Reference: {FaunaDB REST API}[https://faunadb.com/documentation/rest]
151
+ #
152
+ # :category: REST Methods
153
+ def delete(path)
154
+ execute(:delete, path)
36
155
  end
37
156
 
38
- def self.delete(ref, data = {})
39
- connection.delete(ref, data)
157
+ ##
158
+ # Ping FaunaDB.
159
+ #
160
+ # Reference: {FaunaDB Rest API}[https://faunadb.com/documentation#rest-other].
161
+ #
162
+ # :category: REST Methods
163
+ def ping(params = {})
164
+ get 'ping', params
40
165
  end
41
166
 
42
- def self.connection
43
- stack.last || fail(NoContextError, 'You must be within a Fauna::Client.context block to perform operations.')
167
+ private
168
+
169
+ def with_dup
170
+ new_client = self.dup
171
+ yield new_client
172
+ new_client.send(:init_connection)
173
+ new_client
44
174
  end
45
175
 
46
- class << self
47
- private
176
+ def init_credentials(secret)
177
+ @credentials = secret.to_s.split(':', 2)
178
+ end
48
179
 
49
- def stack
50
- Thread.current[:fauna_context_stack] ||= []
180
+ def init_connection
181
+ @connection = Faraday.new(
182
+ url: "#{scheme}://#{domain}:#{port}/",
183
+ headers: {
184
+ 'Accept-Encoding' => 'gzip,deflate',
185
+ 'Content-Type' => 'application/json;charset=utf-8',
186
+ 'User-Agent' => "FaunaDB-Ruby/#{Fauna::VERSION}",
187
+ },
188
+ request: { timeout: read_timeout, open_timeout: connection_timeout },
189
+ ) do |conn|
190
+ # Let us specify arguments so we can set stubs for test adapter
191
+ conn.adapter(*Array(adapter))
192
+ conn.basic_auth(credentials[0].to_s, credentials[1].to_s)
193
+ conn.response :fauna_decode
194
+ end
195
+ end
196
+
197
+ def execute(action, path, query = nil, data = nil)
198
+ path = path.to_s
199
+
200
+ start_time = Time.now
201
+ response = perform_request action, path, query, data
202
+ end_time = Time.now
203
+
204
+ response_raw = response.body
205
+ response_json = FaunaJson.json_load_or_nil response_raw
206
+ response_content = FaunaJson.deserialize response_json unless response_json.nil?
207
+
208
+ request_result = RequestResult.new(self,
209
+ action, path, query, data,
210
+ response_raw, response_content, response.status, response.headers,
211
+ start_time, end_time)
212
+
213
+ @observer.call(request_result) unless @observer.nil?
214
+
215
+ if response_json.nil?
216
+ fail UnexpectedError.new('Invalid JSON.', request_result)
217
+ end
218
+
219
+ FaunaError.raise_for_status_code(request_result)
220
+ UnexpectedError.get_or_raise request_result, response_content, :resource
221
+ end
222
+
223
+ def perform_request(action, path, query, data)
224
+ @connection.send(action) do |req|
225
+ req.params = query.delete_if { |_, v| v.nil? } unless query.nil?
226
+ req.body = FaunaJson.to_json(data) unless data.nil?
227
+ req.url(path || '')
51
228
  end
52
229
  end
53
230
  end
231
+
232
+ # Middleware for decompressing responses
233
+ class FaunaDecode < Faraday::Middleware # :nodoc:
234
+ def call(env)
235
+ @app.call(env).on_complete do |response_env|
236
+ raw_body = response_env[:body]
237
+ response_env[:body] =
238
+ case response_env[:response_headers]['Content-Encoding']
239
+ when 'gzip'
240
+ io = StringIO.new raw_body
241
+ Zlib::GzipReader.new(io, external_encoding: Encoding::UTF_8).read
242
+ when 'deflate'
243
+ Zlib::Inflate.inflate raw_body
244
+ else
245
+ raw_body
246
+ end
247
+ end
248
+ end
249
+ end
250
+
251
+ Faraday::Response.register_middleware fauna_decode: lambda { FaunaDecode }
54
252
  end