fauna 1.3.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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