yax-fauna 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +51 -0
- data/Gemfile +6 -0
- data/LICENSE +12 -0
- data/README.md +148 -0
- data/Rakefile +13 -0
- data/fauna.gemspec +26 -0
- data/lib/fauna.rb +25 -0
- data/lib/fauna/client.rb +253 -0
- data/lib/fauna/client_logger.rb +52 -0
- data/lib/fauna/context.rb +81 -0
- data/lib/fauna/deprecate.rb +29 -0
- data/lib/fauna/errors.rb +235 -0
- data/lib/fauna/json.rb +99 -0
- data/lib/fauna/objects.rb +147 -0
- data/lib/fauna/page.rb +374 -0
- data/lib/fauna/query.rb +899 -0
- data/lib/fauna/request_result.rb +58 -0
- data/lib/fauna/util.rb +50 -0
- data/lib/fauna/version.rb +4 -0
- data/spec/bytes_spec.rb +36 -0
- data/spec/client_logger_spec.rb +73 -0
- data/spec/client_spec.rb +127 -0
- data/spec/context_spec.rb +84 -0
- data/spec/errors_spec.rb +185 -0
- data/spec/fauna_helper.rb +102 -0
- data/spec/json_spec.rb +161 -0
- data/spec/page_spec.rb +357 -0
- data/spec/query_spec.rb +1104 -0
- data/spec/queryv_spec.rb +25 -0
- data/spec/ref_spec.rb +99 -0
- data/spec/setref_spec.rb +23 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/util_spec.rb +19 -0
- metadata +181 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f2163449ff0b2f3f9eb5abff36ae23d33cfb53bb81f8688f4a8b3b1acec51010
|
4
|
+
data.tar.gz: ba7a3a18d2492d6b3b32c052327f7272b1bfdf979a018c6c9b44fc9739dd0386
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1ab8570d7756839afa10ad19411c8928d1db9ee409da600d795382b8dfd98b508f96b05ec6bf7ea54d426e97eec95a05fb999af54a2bd1be6a5c5da97d7eef3d
|
7
|
+
data.tar.gz: 18d9e7727723f47073eb4a957846736351c0af9af881149c5f3c573b42ef9e97f9d1938c60da79b2636b793ee68ba49bc064b5d671eea7358407c14183f026d2
|
data/CHANGELOG
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
4.0.0.pre.1
|
2
|
+
* Adds `ngram` function.
|
3
|
+
* Added `is_empty` and `is_nonempty` functions.
|
4
|
+
* Added `to_string`, `to_number`, `to_time`, and `to_date` functions.
|
5
|
+
* Reverses the argument order of append and prepend functions.
|
6
|
+
* Fixed serialization to correctly wrap objects that implement `to_h` or `to_hash`
|
7
|
+
(unsupported objects are now explictly rejected with a `Fauna::SerializationError`).
|
8
|
+
* Add support for the X-Last-Seen-Txn header
|
9
|
+
|
10
|
+
3.0.0
|
11
|
+
* Adds support for recursive references.
|
12
|
+
* Removed REST api support from `Client`.
|
13
|
+
* Added `abort` function.
|
14
|
+
* Added `normalizer` argument to `casefold` function.
|
15
|
+
* Added `new_id` function.
|
16
|
+
* Deprecated `next_id` function in favor of `new_id`.
|
17
|
+
* Added `identity` and `has_identity` functions.
|
18
|
+
* Added `singleton` and `events` functions.
|
19
|
+
* Added `select_all` function.
|
20
|
+
|
21
|
+
2.4.0
|
22
|
+
* Handle HTTP errors 502 and 504 as `Fauna::UnavailableError`.
|
23
|
+
* Added support for user-defined functions.
|
24
|
+
* Added support for the `@query` type (via `Fauna::QueryV`).
|
25
|
+
* Added `create_function`, `function`, and `call` query functions.
|
26
|
+
|
27
|
+
2.3.0
|
28
|
+
* Change default domain to `db.fauna.com`.
|
29
|
+
* Added `key_from_secret` and `at` query functions.
|
30
|
+
* Added support for `@bytes` type (via `Fauna::Bytes`).
|
31
|
+
|
32
|
+
2.2.0
|
33
|
+
* Added `create_class`, `create_index`, `create_database`, `create_key`, `database`, `class`,
|
34
|
+
and `index` query functions.
|
35
|
+
* Removed `count` query function.
|
36
|
+
* Raises `Fauna::UnavailableError` for all 503s and for Faraday network errors.
|
37
|
+
* Fix documentation errors and update links.
|
38
|
+
|
39
|
+
2.1.2
|
40
|
+
* Change default domain to `cloud.faunadb.com`.
|
41
|
+
|
42
|
+
2.1.1
|
43
|
+
* Use persistent connections (via the `net-http-persistent` adapter) by default.
|
44
|
+
|
45
|
+
2.1.0
|
46
|
+
* Added paginate helper.
|
47
|
+
* Improved exception messages (now include FaunaDB errors).
|
48
|
+
* Added `ref` and `next_id` query functions.
|
49
|
+
|
50
|
+
2.0.0
|
51
|
+
* Complete rewrite for API 2.0. Not backwards compatible with the old client or api.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Copyright 2017 Fauna, Inc.
|
2
|
+
|
3
|
+
Licensed under the Mozilla Public License, Version 2.0 (the "License"); you may
|
4
|
+
not use this software except in compliance with the License. You may obtain a
|
5
|
+
copy of the License at
|
6
|
+
|
7
|
+
http://mozilla.org/MPL/2.0/
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
10
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
11
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
12
|
+
specific language governing permissions and limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
# FaunaDB
|
2
|
+
|
3
|
+
[![Coverage Status](https://img.shields.io/codecov/c/github/fauna/faunadb-ruby/master.svg?maxAge=21600)](https://codecov.io/gh/fauna/faunadb-ruby/branch/master)
|
4
|
+
[![Gem Version](https://img.shields.io/gem/v/fauna.svg?maxAge=21600)](https://rubygems.org/gems/fauna)
|
5
|
+
[![License](https://img.shields.io/badge/license-MPL_2.0-blue.svg?maxAge=2592000)](https://raw.githubusercontent.com/fauna/faunadb-ruby/master/LICENSE)
|
6
|
+
|
7
|
+
Ruby driver for [FaunaDB](https://fauna.com).
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
The FaunaDB ruby driver is distributed as a gem. Install it via:
|
12
|
+
|
13
|
+
$ gem install fauna
|
14
|
+
|
15
|
+
Or if you use Bundler, add it to your application's `Gemfile`:
|
16
|
+
|
17
|
+
gem 'fauna'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
## Documentation
|
24
|
+
|
25
|
+
The driver documentation is [hosted on GitHub Pages](https://fauna.github.io/faunadb-ruby/).
|
26
|
+
|
27
|
+
Please see the [FaunaDB Documentation](https://fauna.com/documentation) for
|
28
|
+
a complete API reference, or look in
|
29
|
+
[`/test`](https://github.com/fauna/faunadb-ruby/tree/master/test) for more
|
30
|
+
examples.
|
31
|
+
|
32
|
+
## Compatibility
|
33
|
+
|
34
|
+
Tested and compatible with the following ruby versions:
|
35
|
+
|
36
|
+
* MRI 1.9.3
|
37
|
+
* MRI 2.2.3
|
38
|
+
* Jruby 1.7.19
|
39
|
+
|
40
|
+
## Basic Usage
|
41
|
+
|
42
|
+
First, require the gem:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
require 'fauna'
|
46
|
+
```
|
47
|
+
|
48
|
+
### Creating a Client
|
49
|
+
|
50
|
+
All API requests pass through a `Fauna::Client`. Creating a client
|
51
|
+
requires either an admin key, server key, client key, or a token.
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
server_key = 'ls8AkXLdakAAAALPAJFy3LvQAAGwDRAS_Prjy6O8VQBfQAlZzwAA'
|
55
|
+
```
|
56
|
+
|
57
|
+
Now we can make a database-level client:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
$fauna = Fauna::Client.new(secret: server_key)
|
61
|
+
```
|
62
|
+
|
63
|
+
You can optionally configure an `observer` on the client. To ease
|
64
|
+
debugging, we provide a simple logging observer at
|
65
|
+
`Fauna::ClientLogger.logger`, which you can configure as such:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
require 'logger'
|
69
|
+
logger = Logger.new(STDERR)
|
70
|
+
observer = Fauna::ClientLogger.logger { |log| logger.debug(log) }
|
71
|
+
|
72
|
+
$fauna = Fauna::Client.new(
|
73
|
+
secret: server_key,
|
74
|
+
observer: observer)
|
75
|
+
```
|
76
|
+
|
77
|
+
### Using the Client
|
78
|
+
|
79
|
+
Now that we have a client, we can start performing queries:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# Create a class
|
83
|
+
$fauna.query { create ref('classes'), name: 'users' }
|
84
|
+
|
85
|
+
# Create an instance of the class
|
86
|
+
taran = $fauna.query do
|
87
|
+
create ref('classes/users'), data: { email: 'taran@example.com' }
|
88
|
+
end
|
89
|
+
|
90
|
+
# Update the instance
|
91
|
+
taran = $fauna.query do
|
92
|
+
update taran[:ref], data: {
|
93
|
+
name: 'Taran',
|
94
|
+
profession: 'Pigkeeper'
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
# Page through a set
|
99
|
+
pigkeepers = Fauna::Query.expr { match(ref('indexes/users_by_profession'), 'Pigkeeper') }
|
100
|
+
oracles = Fauna::Query.expr { match(ref('indexes/users_by_profession'), 'Oracle') }
|
101
|
+
|
102
|
+
$fauna.query { paginate(union(pigkeepers, oracles)) }
|
103
|
+
|
104
|
+
# Delete the user
|
105
|
+
$fauna.query { delete taran[:ref] }
|
106
|
+
```
|
107
|
+
|
108
|
+
## Running Tests
|
109
|
+
|
110
|
+
You can run tests against FaunaDB Cloud yourself.
|
111
|
+
[Create an admin key](https://fauna.com/account/keys) and set
|
112
|
+
`FAUNA_ROOT_KEY` environment variable to it's secret. Then run `rake spec`:
|
113
|
+
|
114
|
+
```bash
|
115
|
+
export FAUNA_ROOT_KEY='kqnPAbijGhkgAAC03-36hjCvcTnWf4Pl8w97UE1HeWo'
|
116
|
+
rake spec
|
117
|
+
```
|
118
|
+
|
119
|
+
To run a single test, use e.g. `ruby test/client_test.rb`.
|
120
|
+
|
121
|
+
Coverage is automatically run as part of the tests. After running tests, check
|
122
|
+
`coverage/index.html` for the coverage report. If using jruby, use
|
123
|
+
`JRUBY_OPTS="--debug" bundle exec rake spec` to ensure coverage is generated
|
124
|
+
correctly.
|
125
|
+
|
126
|
+
Tests can also be run via a Docker container with
|
127
|
+
`FAUNA_ROOT_KEY="your-cloud-secret" make docker-test` (an alternate
|
128
|
+
Alpine-based Ruby image can be provided via `RUNTIME_IMAGE`).
|
129
|
+
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
GitHub pull requests are very welcome.
|
133
|
+
|
134
|
+
## LICENSE
|
135
|
+
|
136
|
+
Copyright 2017 [Fauna, Inc.](https://fauna.com/)
|
137
|
+
|
138
|
+
Licensed under the Mozilla Public License, Version 2.0 (the
|
139
|
+
"License"); you may not use this software except in compliance with
|
140
|
+
the License. You may obtain a copy of the License at
|
141
|
+
|
142
|
+
[http://mozilla.org/MPL/2.0/](http://mozilla.org/MPL/2.0/)
|
143
|
+
|
144
|
+
Unless required by applicable law or agreed to in writing, software
|
145
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147
|
+
implied. See the License for the specific language governing
|
148
|
+
permissions and limitations under the License.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'rdoc/task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
RDoc::Task.new do |rdoc|
|
7
|
+
rdoc.main = 'README.md'
|
8
|
+
rdoc.rdoc_dir = 'doc'
|
9
|
+
rdoc.rdoc_files.include('README.md', 'lib/fauna.rb', 'lib/fauna/*.rb')
|
10
|
+
end
|
11
|
+
|
12
|
+
task prerelease: [:spec, :install]
|
13
|
+
task default: :spec
|
data/fauna.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require './lib/fauna/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = 'yax-fauna'
|
6
|
+
s.version = Fauna::VERSION.dup
|
7
|
+
s.author = 'Forked from Fauna, Inc.'
|
8
|
+
s.email = 'daniel@danielkehoe.com'
|
9
|
+
s.summary = 'FaunaDB Ruby driver'
|
10
|
+
s.description = 'Ruby driver for FaunaDB.'
|
11
|
+
s.homepage = 'https://github.com/yaxdotcom/yax-faunadb-ruby'
|
12
|
+
s.license = 'MPL-2.0'
|
13
|
+
|
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']
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'faraday', '~> 1.0'
|
21
|
+
s.add_runtime_dependency 'net-http-persistent', '~> 2.9'
|
22
|
+
s.add_runtime_dependency 'json', '~> 2.3'
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.4'
|
24
|
+
s.add_development_dependency 'simplecov-json', '~> 0.2.0'
|
25
|
+
s.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
|
26
|
+
end
|
data/lib/fauna.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'logger'
|
3
|
+
require 'uri'
|
4
|
+
require 'faraday'
|
5
|
+
require 'cgi'
|
6
|
+
require 'zlib'
|
7
|
+
require 'time'
|
8
|
+
require 'base64'
|
9
|
+
|
10
|
+
##
|
11
|
+
# Main namespace for the FaunaDB driver.
|
12
|
+
module Fauna; end
|
13
|
+
|
14
|
+
require 'fauna/deprecate'
|
15
|
+
require 'fauna/version'
|
16
|
+
require 'fauna/util'
|
17
|
+
require 'fauna/errors'
|
18
|
+
require 'fauna/client'
|
19
|
+
require 'fauna/client_logger'
|
20
|
+
require 'fauna/context'
|
21
|
+
require 'fauna/objects'
|
22
|
+
require 'fauna/query'
|
23
|
+
require 'fauna/json'
|
24
|
+
require 'fauna/page'
|
25
|
+
require 'fauna/request_result'
|
data/lib/fauna/client.rb
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Fauna
|
4
|
+
##
|
5
|
+
# The Ruby client for FaunaDB.
|
6
|
+
#
|
7
|
+
# All methods return a converted JSON response.
|
8
|
+
# This is a Hash containing Arrays, ints, floats, strings, and other Hashes.
|
9
|
+
# Hash keys are always Symbols.
|
10
|
+
#
|
11
|
+
# Any Ref, SetRef, Time or Date values in it will also be parsed.
|
12
|
+
# (So instead of <code>{ "@ref": { "id": "123", "class": { "@ref": { "id": "frogs", "class": { "@ref": { "id": "classes" } } } } } }</code>,
|
13
|
+
# you will get <code>Fauna::Ref.new("123", Fauna::Ref.new("frogs", Fauna::Native.classes))</code>).
|
14
|
+
class Client
|
15
|
+
# The domain requests will be sent to.
|
16
|
+
attr_reader :domain
|
17
|
+
# Scheme used when sending requests (either +http+ or +https+).
|
18
|
+
attr_reader :scheme
|
19
|
+
# Port used when sending requests.
|
20
|
+
attr_reader :port
|
21
|
+
# An array of the user and pass used for authentication when sending requests.
|
22
|
+
attr_reader :credentials
|
23
|
+
# Read timeout in seconds.
|
24
|
+
attr_reader :read_timeout
|
25
|
+
# Open timeout in seconds.
|
26
|
+
attr_reader :connection_timeout
|
27
|
+
# Callback that will be passed a +RequestResult+ after every completed request.
|
28
|
+
attr_reader :observer
|
29
|
+
# Faraday[https://github.com/lostisland/faraday] adapter in use.
|
30
|
+
attr_reader :adapter
|
31
|
+
|
32
|
+
# Maintains a thread-safe last seen transaction time. Clients
|
33
|
+
# copied using #with_secret will share the same LastSeen object.
|
34
|
+
class LastSeen
|
35
|
+
def initialize()
|
36
|
+
@mutex = Mutex.new
|
37
|
+
@time = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def time
|
41
|
+
@mutex.synchronize do
|
42
|
+
@time
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def update(time)
|
47
|
+
@mutex.synchronize do
|
48
|
+
if @time.nil?
|
49
|
+
@time = time
|
50
|
+
elsif @time < time
|
51
|
+
@time = time
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Create a new Client.
|
60
|
+
#
|
61
|
+
# +params+:: A list of parameters to configure the connection with.
|
62
|
+
# +:domain+:: The domain to send requests to.
|
63
|
+
# +:scheme+:: Scheme to use when sending requests (either +http+ or +https+).
|
64
|
+
# +:port+:: Port to use when sending requests.
|
65
|
+
# +:secret+:: Credentials to use when sending requests. User and pass must be separated by a colon.
|
66
|
+
# +:read_timeout+:: Read timeout in seconds.
|
67
|
+
# +:connection_timeout+:: Open timeout in seconds.
|
68
|
+
# +:observer+:: Callback that will be passed a RequestResult after every completed request.
|
69
|
+
# +:adapter+:: Faraday[https://github.com/lostisland/faraday] adapter to use. Either can be a symbol for the adapter, or an array of arguments.
|
70
|
+
def initialize(params = {})
|
71
|
+
@domain = params[:domain] || 'db.fauna.com'
|
72
|
+
@scheme = params[:scheme] || 'https'
|
73
|
+
@port = params[:port] || (scheme == 'https' ? 443 : 80)
|
74
|
+
@read_timeout = params[:read_timeout] || 60
|
75
|
+
@connection_timeout = params[:connection_timeout] || 60
|
76
|
+
@observer = params[:observer]
|
77
|
+
@adapter = params[:adapter] || :net_http_persistent
|
78
|
+
@last_seen = LastSeen.new
|
79
|
+
init_credentials(params[:secret])
|
80
|
+
|
81
|
+
init_connection
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Create a new client from the existing config with a given secret.
|
86
|
+
#
|
87
|
+
# +:secret+:: Credentials to use when sending requests. User and pass must be separated by a colon.
|
88
|
+
def with_secret(secret)
|
89
|
+
with_dup do |client|
|
90
|
+
client.send(:init_credentials, secret)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Issues a query to FaunaDB.
|
96
|
+
#
|
97
|
+
# Queries are built via the Query helpers. See {FaunaDB Query API}[https://fauna.com/documentation/queries]
|
98
|
+
# for information on constructing queries.
|
99
|
+
#
|
100
|
+
# +expression+:: A query expression
|
101
|
+
# +expr_block+:: May be provided instead of expression. Block is used to build an expression with Fauna.query.
|
102
|
+
#
|
103
|
+
# Example using expression:
|
104
|
+
#
|
105
|
+
# <code>client.query(Fauna::Query.add(1, 2, Fauna::Query.subtract(3, 2)))</code>
|
106
|
+
#
|
107
|
+
# Example using block:
|
108
|
+
#
|
109
|
+
# <code>client.query { add(1, 2, subtract(3, 2)) }</code>
|
110
|
+
#
|
111
|
+
# Reference: {Executing FaunaDB Queries}[https://fauna.com/documentation#queries]
|
112
|
+
#
|
113
|
+
# :category: Query Methods
|
114
|
+
def query(expression = nil, &expr_block)
|
115
|
+
if expr_block.nil?
|
116
|
+
execute(:post, :'', nil, Fauna::Query::Expr.wrap(expression))
|
117
|
+
else
|
118
|
+
execute(:post, :'', nil, Fauna::Query.expr(&expr_block))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Creates a Fauna::Page for paging/iterating over a set.
|
124
|
+
#
|
125
|
+
# +set+:: A set query to paginate over.
|
126
|
+
# +params+:: A list of parameters to pass to {paginate}[https://fauna.com/documentation/queries#read_functions-paginate_set].
|
127
|
+
# +fauna_map+:: Optional block to wrap the generated paginate query with. The block will be run in a query context.
|
128
|
+
# The paginate query will be passed into the block as an argument.
|
129
|
+
def paginate(set, params = {}, &fauna_map)
|
130
|
+
Fauna::Page.new(self, set, params, &fauna_map)
|
131
|
+
end
|
132
|
+
|
133
|
+
##
|
134
|
+
# Ping FaunaDB.
|
135
|
+
#
|
136
|
+
# Reference: {FaunaDB Rest API}[https://fauna.com/documentation#rest-other].
|
137
|
+
#
|
138
|
+
# :category: REST Methods
|
139
|
+
def ping(params = {})
|
140
|
+
execute(:get, :ping, params)
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def with_dup
|
146
|
+
new_client = self.dup
|
147
|
+
yield new_client
|
148
|
+
new_client.send(:init_connection)
|
149
|
+
new_client
|
150
|
+
end
|
151
|
+
|
152
|
+
def init_credentials(secret)
|
153
|
+
@credentials = secret.to_s.split(':', 2)
|
154
|
+
end
|
155
|
+
|
156
|
+
def init_connection
|
157
|
+
@connection = Faraday.new(
|
158
|
+
url: "#{scheme}://#{domain}:#{port}/",
|
159
|
+
headers: {
|
160
|
+
'Accept-Encoding' => 'gzip,deflate',
|
161
|
+
'Content-Type' => 'application/json;charset=utf-8',
|
162
|
+
'User-Agent' => "FaunaDB-Ruby/#{Fauna::VERSION}",
|
163
|
+
'X-FaunaDB-API-Version' => '2.1'
|
164
|
+
},
|
165
|
+
request: { timeout: read_timeout, open_timeout: connection_timeout },
|
166
|
+
) do |conn|
|
167
|
+
# Let us specify arguments so we can set stubs for test adapter
|
168
|
+
conn.adapter(*Array(adapter))
|
169
|
+
conn.basic_auth(credentials[0].to_s, credentials[1].to_s)
|
170
|
+
conn.response :fauna_decode
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def execute(action, path, query = nil, data = nil)
|
175
|
+
path = path.to_s
|
176
|
+
|
177
|
+
start_time = Time.now
|
178
|
+
begin
|
179
|
+
response = perform_request action, path, query, data
|
180
|
+
rescue Faraday::ClientError => e
|
181
|
+
end_time = Time.now
|
182
|
+
|
183
|
+
message = e.class.name
|
184
|
+
message += ": #{e.message}" unless e.message.nil?
|
185
|
+
|
186
|
+
request_result = RequestResult.new(self,
|
187
|
+
action, path, query, data,
|
188
|
+
nil, nil, nil, nil,
|
189
|
+
start_time, end_time)
|
190
|
+
raise UnexpectedError.new(message, request_result)
|
191
|
+
end
|
192
|
+
end_time = Time.now
|
193
|
+
|
194
|
+
response_raw = response.body
|
195
|
+
response_json = FaunaJson.json_load_or_nil response_raw
|
196
|
+
response_content = FaunaJson.deserialize response_json unless response_json.nil?
|
197
|
+
|
198
|
+
request_result = RequestResult.new(self,
|
199
|
+
action, path, query, data,
|
200
|
+
response_raw, response_content, response.status, response.headers,
|
201
|
+
start_time, end_time)
|
202
|
+
|
203
|
+
|
204
|
+
if response.headers.key?('X-Txn-Time')
|
205
|
+
time = response.headers['X-Txn-Time'].to_i
|
206
|
+
|
207
|
+
@last_seen.update(time)
|
208
|
+
end
|
209
|
+
|
210
|
+
@observer.call(request_result) unless @observer.nil?
|
211
|
+
|
212
|
+
FaunaError.raise_for_status_code(request_result)
|
213
|
+
UnexpectedError.get_or_raise request_result, response_content, :resource
|
214
|
+
end
|
215
|
+
|
216
|
+
def perform_request(action, path, query, data)
|
217
|
+
@connection.send(action) do |req|
|
218
|
+
req.params = query.delete_if { |_, v| v.nil? } unless query.nil?
|
219
|
+
req.body = FaunaJson.to_json(data) unless data.nil?
|
220
|
+
|
221
|
+
last_txn = @last_seen.time
|
222
|
+
unless last_txn.nil?
|
223
|
+
req.headers['X-Last-Seen-Txn'] = last_txn.to_s
|
224
|
+
end
|
225
|
+
|
226
|
+
req.url(path || '')
|
227
|
+
end
|
228
|
+
rescue Faraday::ConnectionFailed, Faraday::TimeoutError, Faraday::SSLError => e
|
229
|
+
raise UnavailableError.new(e)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
# Middleware for decompressing responses
|
234
|
+
class FaunaDecode < Faraday::Middleware # :nodoc:
|
235
|
+
def call(env)
|
236
|
+
@app.call(env).on_complete do |response_env|
|
237
|
+
raw_body = response_env[:body]
|
238
|
+
response_env[:body] =
|
239
|
+
case response_env[:response_headers]['Content-Encoding']
|
240
|
+
when 'gzip'
|
241
|
+
io = StringIO.new raw_body
|
242
|
+
Zlib::GzipReader.new(io, external_encoding: Encoding::UTF_8).read
|
243
|
+
when 'deflate'
|
244
|
+
Zlib::Inflate.inflate raw_body
|
245
|
+
else
|
246
|
+
raw_body
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
Faraday::Response.register_middleware fauna_decode: lambda { FaunaDecode }
|
253
|
+
end
|